10e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
20e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include <stdio.h>
30e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include <stdlib.h>
40e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include <assert.h>
50e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
60e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgtypedef unsigned long long int ULong;
70e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgtypedef unsigned int   UInt;
80e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgtypedef unsigned short UShort;
90e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgtypedef unsigned char  UChar;
100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgtypedef signed int    Int;
120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgtypedef signed short  Short;
130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgtypedef signed long int  Word;
150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org/* ------------ MEM, Q ------------ */
170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgULong btsq_mem ( char* base, Word bitno )
190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org{
200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   UChar res;
210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   __asm__
220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   __volatile__("btsq\t%2, %0\n\t"
230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                "setc\t%1"
240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                : "=m" (*base), "=q" (res)
250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                : "r" (bitno));
260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   /* Pretty meaningless to dereference base here, but that's what you
270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      have to do to get a btsl insn which refers to memory starting at
280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      base. */
290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   return res;
300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
31cf81adffe15fa8ea0f333432e41f6d504148f18abuildbot@webrtc.org
320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgULong btrq_mem ( char* base, Word bitno )
332a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org{
340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   UChar res;
350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   __asm__
360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   __volatile__("btrq\t%2, %0\n\t"
370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                "setc\t%1"
380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                : "=m" (*base), "=q" (res)
390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                : "r" (bitno));
400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   return res;
410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgULong btcq_mem ( char* base, Word bitno )
440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org{
450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   UChar res;
460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   __asm__
470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   __volatile__("btcq\t%2, %0\n\t"
480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                "setc\t%1"
490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                : "=m" (*base), "=q" (res)
500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                : "r" (bitno));
510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   return res;
520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgULong btq_mem ( char* base, Word bitno )
550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org{
560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   UChar res;
570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   __asm__
580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   __volatile__("btq\t%2, %0\n\t"
590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                "setc\t%1"
6065ab28e69ec9341c282f5ba656dbaa8a5d1671c0niklas.enbom@webrtc.org                : "=m" (*base), "=q" (res)
6165ab28e69ec9341c282f5ba656dbaa8a5d1671c0niklas.enbom@webrtc.org                : "r" (bitno)
620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                : "cc", "memory");
63a26d7d6ee1c4d74b8996d19dbb46fc130df3ac17buildbot@webrtc.org   return res;
6434f765950b7a4adb07c284f4522e2a64c9364affglaznev@webrtc.org}
6534f765950b7a4adb07c284f4522e2a64c9364affglaznev@webrtc.org
6634f765950b7a4adb07c284f4522e2a64c9364affglaznev@webrtc.org
6734f765950b7a4adb07c284f4522e2a64c9364affglaznev@webrtc.org/* ------------ MEM, L ------------ */
6834f765950b7a4adb07c284f4522e2a64c9364affglaznev@webrtc.org
6934f765950b7a4adb07c284f4522e2a64c9364affglaznev@webrtc.orgULong btsl_mem ( char* base, Word bitno )
706a9dda84d595cd6d4172ed395122300b64c5eea2glaznev@webrtc.org{
716a9dda84d595cd6d4172ed395122300b64c5eea2glaznev@webrtc.org   UChar res;
7234f765950b7a4adb07c284f4522e2a64c9364affglaznev@webrtc.org   __asm__
730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   __volatile__("btsl\t%2, %0\n\t"
740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                "setc\t%1"
750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                : "=m" (*base), "=q" (res)
760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                : "r" ((Int)bitno));
770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   /* Pretty meaningless to dereference base here, but that's what you
780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      have to do to get a btsl insn which refers to memory starting at
790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      base. */
800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   return res;
810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgULong btrl_mem ( char* base, Word bitno )
840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org{
850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   UChar res;
860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   __asm__
870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   __volatile__("btrl\t%2, %0\n\t"
880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                "setc\t%1"
890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                : "=m" (*base), "=q" (res)
900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                : "r" ((Int)bitno));
910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   return res;
920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgULong btcl_mem ( char* base, Word bitno )
950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org{
960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   UChar res;
970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   __asm__
980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   __volatile__("btcl\t%2, %0\n\t"
990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                "setc\t%1"
1000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                : "=m" (*base), "=q" (res)
1010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                : "r" ((Int)bitno));
1020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   return res;
1030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgULong btl_mem ( char* base, Word bitno )
1060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org{
1070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   UChar res;
1080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   __asm__
1090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   __volatile__("btl\t%2, %0\n\t"
1100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                "setc\t%1"
1110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                : "=m" (*base), "=q" (res)
1120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                : "r" ((Int)bitno)
1130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                : "cc", "memory");
1140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   return res;
1150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org/* ------------ MEM, W ------------ */
1200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgULong btsw_mem ( char* base, Word bitno )
1220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org{
1230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   UChar res;
1240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   __asm__
1250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   __volatile__("btsw\t%2, %0\n\t"
1260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                "setc\t%1"
1270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                : "=m" (*base), "=q" (res)
1280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                : "r" ((Short)bitno));
1290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   /* Pretty meaningless to dereference base here, but that's what you
1300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      have to do to get a btsl insn which refers to memory starting at
1310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org      base. */
1320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   return res;
1330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgULong btrw_mem ( char* base, Word bitno )
1360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org{
1370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   UChar res;
1380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   __asm__
1390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   __volatile__("btrw\t%2, %0\n\t"
1400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                "setc\t%1"
1410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                : "=m" (*base), "=q" (res)
1420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                : "r" ((Short)bitno));
1430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   return res;
1440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
146b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.orgULong btcw_mem ( char* base, Word bitno )
147b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org{
148b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org   UChar res;
149b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org   __asm__
150b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org   __volatile__("btcw\t%2, %0\n\t"
151b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org                "setc\t%1"
152b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org                : "=m" (*base), "=q" (res)
153b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org                : "r" ((Short)bitno));
154b881d27f23e9a8f52dc6a60fc66ebd75f9c2f15cmallinath@webrtc.org   return res;
1550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgULong btw_mem ( char* base, Word bitno )
1580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org{
1590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   UChar res;
1600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   __asm__
1610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   __volatile__("btw\t%2, %0\n\t"
1620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                "setc\t%1"
1630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                : "=m" (*base), "=q" (res)
1640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                : "r" ((Short)bitno)
1650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                : "cc", "memory");
1660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   return res;
1670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org/* ------------ REG, Q ------------ */
1720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgULong btsq_reg ( ULong reg_in, Word bitno,
1740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                        ULong* reg_out_p )
1750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org{
1760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   UChar res;
1770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   ULong reg_out;
1780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   __asm__
1790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   __volatile__("movq\t%3, %%rax\n\t"
1800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                "btsq\t%2, %%rax\n\t"
1810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                "movq\t%%rax, %1\n\t"
1820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                "setc\t%0"
1830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                : "=q" (res), "=r" (reg_out)
1840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                : "r" (bitno), "r" (reg_in)
1850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                : "cc", "eax");
1860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   *reg_out_p = reg_out;
1870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   return res;
1880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org}
1890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org
1910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgULong btrq_reg ( ULong reg_in, Word bitno,
1920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                        ULong* reg_out_p )
1930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org{
1940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   UChar res;
1950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   ULong reg_out;
1960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   __asm__
1970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   __volatile__("movq\t%3, %%rax\n\t"
1980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                "btrq\t%2, %%rax\n\t"
1990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                "movq\t%%rax, %1\n\t"
2000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                "setc\t%0"
2010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                : "=q" (res), "=r" (reg_out)
2020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                : "r" (bitno), "r" (reg_in)
2030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org                : "cc", "eax");
2040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org   *reg_out_p = reg_out;
205   return res;
206}
207
208
209ULong btcq_reg ( ULong reg_in, Word bitno,
210                        ULong* reg_out_p )
211{
212   UChar res;
213   ULong reg_out;
214   __asm__
215   __volatile__("movq\t%3, %%rax\n\t"
216                "btcq\t%2, %%rax\n\t"
217                "movq\t%%rax, %1\n\t"
218                "setc\t%0"
219                : "=q" (res), "=r" (reg_out)
220                : "r" (bitno), "r" (reg_in)
221                : "cc", "eax");
222   *reg_out_p = reg_out;
223   return res;
224}
225
226
227ULong btq_reg ( ULong reg_in, Word bitno,
228                       ULong* reg_out_p )
229{
230   UChar res;
231   ULong reg_out;
232   __asm__
233   __volatile__("movq\t%3, %%rax\n\t"
234                "btq\t%2, %%rax\n\t"
235                "movq\t%%rax, %1\n\t"
236                "setc\t%0"
237                : "=q" (res), "=r" (reg_out)
238                : "r" (bitno), "r" (reg_in)
239                : "cc", "eax");
240   *reg_out_p = reg_out;
241   return res;
242}
243
244
245
246/* ------------ REG, L ------------ */
247
248ULong btsl_reg ( ULong reg_in, Word bitno,
249                        ULong* reg_out_p )
250{
251   UChar res;
252   ULong reg_out;
253   __asm__
254   __volatile__("movq\t%3, %%rax\n\t"
255                "btsl\t%2, %%eax\n\t"
256                "movq\t%%rax, %1\n\t"
257                "setc\t%0"
258                : "=q" (res), "=r" (reg_out)
259                : "r" ((Int)bitno), "r" (reg_in)
260                : "cc", "eax");
261   *reg_out_p = reg_out;
262   return res;
263}
264
265
266ULong btrl_reg ( ULong reg_in, Word bitno,
267                        ULong* reg_out_p )
268{
269   UChar res;
270   ULong reg_out;
271   __asm__
272   __volatile__("movq\t%3, %%rax\n\t"
273                "btrl\t%2, %%eax\n\t"
274                "movq\t%%rax, %1\n\t"
275                "setc\t%0"
276                : "=q" (res), "=r" (reg_out)
277                : "r" ((Int)bitno), "r" (reg_in)
278                : "cc", "eax");
279   *reg_out_p = reg_out;
280   return res;
281}
282
283
284ULong btcl_reg ( ULong reg_in, Word bitno,
285                        ULong* reg_out_p )
286{
287   UChar res;
288   ULong reg_out;
289   __asm__
290   __volatile__("movq\t%3, %%rax\n\t"
291                "btcl\t%2, %%eax\n\t"
292                "movq\t%%rax, %1\n\t"
293                "setc\t%0"
294                : "=q" (res), "=r" (reg_out)
295                : "r" ((Int)bitno), "r" (reg_in)
296                : "cc", "eax");
297   *reg_out_p = reg_out;
298   return res;
299}
300
301
302ULong btl_reg ( ULong reg_in, Word bitno,
303                       ULong* reg_out_p )
304{
305   UChar res;
306   ULong reg_out;
307   __asm__
308   __volatile__("movq\t%3, %%rax\n\t"
309                "btl\t%2, %%eax\n\t"
310                "movq\t%%rax, %1\n\t"
311                "setc\t%0"
312                : "=q" (res), "=r" (reg_out)
313                : "r" ((Int)bitno), "r" (reg_in)
314                : "cc", "eax");
315   *reg_out_p = reg_out;
316   return res;
317}
318
319
320
321/* ------------ REG, W ------------ */
322
323ULong btsw_reg ( ULong reg_in, Word bitno,
324                        ULong* reg_out_p )
325{
326   UChar res;
327   ULong reg_out;
328   __asm__
329   __volatile__("movq\t%3, %%rax\n\t"
330                "btsw\t%2, %%ax\n\t"
331                "movq\t%%rax, %1\n\t"
332                "setc\t%0"
333                : "=q" (res), "=r" (reg_out)
334                : "r" ((Short)bitno), "r" (reg_in)
335                : "cc", "eax");
336   *reg_out_p = reg_out;
337   return res;
338}
339
340
341ULong btrw_reg ( ULong reg_in, Word bitno,
342                        ULong* reg_out_p )
343{
344   UChar res;
345   ULong reg_out;
346   __asm__
347   __volatile__("movq\t%3, %%rax\n\t"
348                "btrw\t%2, %%ax\n\t"
349                "movq\t%%rax, %1\n\t"
350                "setc\t%0"
351                : "=q" (res), "=r" (reg_out)
352                : "r" ((Short)bitno), "r" (reg_in)
353                : "cc", "eax");
354   *reg_out_p = reg_out;
355   return res;
356}
357
358
359ULong btcw_reg ( ULong reg_in, Word bitno,
360                        ULong* reg_out_p )
361{
362   UChar res;
363   ULong reg_out;
364   __asm__
365   __volatile__("movq\t%3, %%rax\n\t"
366                "btcw\t%2, %%ax\n\t"
367                "movq\t%%rax, %1\n\t"
368                "setc\t%0"
369                : "=q" (res), "=r" (reg_out)
370                : "r" ((Short)bitno), "r" (reg_in)
371                : "cc", "eax");
372   *reg_out_p = reg_out;
373   return res;
374}
375
376
377ULong btw_reg ( ULong reg_in, Word bitno,
378                       ULong* reg_out_p )
379{
380   UChar res;
381   ULong reg_out;
382   __asm__
383   __volatile__("movq\t%3, %%rax\n\t"
384                "btw\t%2, %%ax\n\t"
385                "movq\t%%rax, %1\n\t"
386                "setc\t%0"
387                : "=q" (res), "=r" (reg_out)
388                : "r" ((Short)bitno), "r" (reg_in)
389                : "cc", "eax");
390   *reg_out_p = reg_out;
391   return res;
392}
393
394
395
396
397
398
399
400ULong rol1 ( ULong x )
401{
402  return (x << 1) | (x >> 63);
403}
404
405int main ( void )
406{
407   UInt   n, op;
408   ULong  carrydep, c, res;
409   char*  block;
410   ULong  reg;
411   Word   bitoff;
412
413   /*------------------------ MEM-L -----------------------*/
414
415   carrydep = 0;
416   block = calloc(200,1);
417   block += 100;
418   /* Valid bit offsets are -800 .. 799 inclusive. */
419
420   for (n = 0; n < 10000; n++) {
421      bitoff = (random() % 1600) - 800;
422      op = random() % 12;
423      c = 2;
424      switch (op) {
425         case  0: c = btsl_mem(block, bitoff); break;
426         case  1: c = btrl_mem(block, bitoff); break;
427         case  2: c = btcl_mem(block, bitoff); break;
428         case  3: c =  btl_mem(block, bitoff); break;
429         case  4: c = btsq_mem(block, bitoff); break;
430         case  5: c = btrq_mem(block, bitoff); break;
431         case  6: c = btcq_mem(block, bitoff); break;
432         case  7: c =  btq_mem(block, bitoff); break;
433         case  8: c = btsw_mem(block, bitoff); break;
434         case  9: c = btrw_mem(block, bitoff); break;
435         case 10: c = btcw_mem(block, bitoff); break;
436         case 11: c =  btw_mem(block, bitoff); break;
437         default: assert(0);
438      }
439      assert(c == 0 || c == 1);
440      carrydep = c ? (rol1(carrydep) ^ bitoff) : carrydep;
441   }
442
443   /* Compute final result */
444   block -= 100;
445   res = 0;
446   for (n = 0; n < 200; n++) {
447      UChar ch = block[n];
448      /* printf("%d ", (int)block[n]); */
449      res = rol1(res) ^ (UInt)ch;
450   }
451
452   printf("MEM-L: final res 0x%llx, carrydep 0x%llx\n", res, carrydep);
453
454   /*------------------------ REG-L -----------------------*/
455
456   carrydep = 0;
457   reg = 0;
458
459   for (n = 0; n < 1000; n++) {
460      bitoff = (random() % 100) - 50;
461      op = random() % 12;
462      c = 2;
463      switch (op) {
464         case  0: c = btsl_reg(reg, bitoff, &reg); break;
465         case  1: c = btrl_reg(reg, bitoff, &reg); break;
466         case  2: c = btcl_reg(reg, bitoff, &reg); break;
467         case  3: c =  btl_reg(reg, bitoff, &reg); break;
468         case  4: c = btsq_reg(reg, bitoff, &reg); break;
469         case  5: c = btrq_reg(reg, bitoff, &reg); break;
470         case  6: c = btcq_reg(reg, bitoff, &reg); break;
471         case  7: c =  btq_reg(reg, bitoff, &reg); break;
472         case  8: c = btsw_reg(reg, bitoff, &reg); break;
473         case  9: c = btrw_reg(reg, bitoff, &reg); break;
474         case 10: c = btcw_reg(reg, bitoff, &reg); break;
475         case 11: c =  btw_reg(reg, bitoff, &reg); break;
476         default: assert(0);
477      }
478      assert(c == 0 || c == 1);
479      carrydep = c ? (rol1(carrydep) ^ bitoff) : carrydep;
480   }
481
482   printf("REG-L: final res 0x%llx, carrydep 0x%llx\n", reg, carrydep);
483
484   block += 100;
485
486   /* Just try one of these at once; more than one can cause a
487      confusing merging of error messages. */
488   //btsl_mem(block, -800);  /* should not complain */
489   //btsl_mem(block, -801);  /* should complain */
490   //btsl_mem(block, 799);   /* should not complain */
491   //btsl_mem(block, 800);   /* should complain */
492
493   block -= 100;
494   free(block);
495
496   return 0;
497}
498
499