1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdio.h> 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdlib.h> 4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <assert.h> 5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownunsigned int btsl_mem ( char* base, int bitno ) 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned char res; 10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ 11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __volatile__("btsl\t%2, %0\n\t" 12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "setc\t%1" 13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "=m" (*base), "=q" (res) 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "r" (bitno)); 15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Pretty meaningless to dereference base here, but that's what you 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown have to do to get a btsl insn which refers to memory starting at 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown base. */ 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return res; 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownunsigned int btrl_mem ( char* base, int bitno ) 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned char res; 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __volatile__("btrl\t%2, %0\n\t" 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "setc\t%1" 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "=m" (*base), "=q" (res) 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "r" (bitno)); 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return res; 30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownunsigned int btcl_mem ( char* base, int bitno ) 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned char res; 35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __volatile__("btcl\t%2, %0\n\t" 37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "setc\t%1" 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "=m" (*base), "=q" (res) 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "r" (bitno)); 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return res; 41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownunsigned int btl_mem ( char* base, int bitno ) 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned char res; 46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ 47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __volatile__("btl\t%2, %0\n\t" 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "setc\t%1" 49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "=m" (*base), "=q" (res) 50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "r" (bitno) 51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "cc", "memory"); 52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return res; 53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownunsigned int btsl_reg ( unsigned int reg_in, int bitno, 59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned int* reg_out_p ) 60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned char res; 62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned int reg_out; 63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ 64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __volatile__("movl\t%3, %%eax\n\t" 65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "btsl\t%2, %%eax\n\t" 66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "movl\t%%eax, %1\n\t" 67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "setc\t%0" 68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "=q" (res), "=r" (reg_out) 69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "r" (bitno), "r" (reg_in) 70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "cc", "eax"); 71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *reg_out_p = reg_out; 72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return res; 73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownunsigned int btrl_reg ( unsigned int reg_in, int bitno, 77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned int* reg_out_p ) 78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned char res; 80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned int reg_out; 81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ 82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __volatile__("movl\t%3, %%eax\n\t" 83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "btrl\t%2, %%eax\n\t" 84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "movl\t%%eax, %1\n\t" 85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "setc\t%0" 86ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "=q" (res), "=r" (reg_out) 87ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "r" (bitno), "r" (reg_in) 88ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "cc", "eax"); 89ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *reg_out_p = reg_out; 90ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return res; 91ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 92ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 93ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 94ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownunsigned int btcl_reg ( unsigned int reg_in, int bitno, 95ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned int* reg_out_p ) 96ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 97ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned char res; 98ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned int reg_out; 99ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ 100ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __volatile__("movl\t%3, %%eax\n\t" 101ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "btcl\t%2, %%eax\n\t" 102ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "movl\t%%eax, %1\n\t" 103ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "setc\t%0" 104ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "=q" (res), "=r" (reg_out) 105ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "r" (bitno), "r" (reg_in) 106ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "cc", "eax"); 107ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *reg_out_p = reg_out; 108ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return res; 109ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 110ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 111ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 112ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownunsigned int btl_reg ( unsigned int reg_in, int bitno, 113ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned int* reg_out_p ) 114ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 115ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned char res; 116ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown unsigned int reg_out; 117ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __asm__ 118ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown __volatile__("movl\t%3, %%eax\n\t" 119ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "btl\t%2, %%eax\n\t" 120ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "movl\t%%eax, %1\n\t" 121ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "setc\t%0" 122ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "=q" (res), "=r" (reg_out) 123ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "r" (bitno), "r" (reg_in) 124ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown : "cc", "eax"); 125ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown *reg_out_p = reg_out; 126ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return res; 127ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 128ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 129ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 130ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 131ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 132ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 133ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 134ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 135ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef unsigned int UInt; 136ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef unsigned char UChar; 137ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 138ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff BrownUInt rol1 ( UInt x ) 139ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 140ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return (x << 1) | (x >> 31); 141ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 142ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 143ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint main ( void ) 144ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 145ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt n, bitoff, op; 146ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt carrydep, c, res; 147ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar* block; 148ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UInt reg; 149ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 150ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*------------------------ MEM-L -----------------------*/ 151ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 152ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown carrydep = 0; 153ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown block = calloc(200,1); 154ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown block += 100; 155ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Valid bit offsets are -800 .. 799 inclusive. */ 156ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 157ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (n = 0; n < 10000; n++) { 158ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bitoff = (random() % 1600) - 800; 159ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown op = random() % 4; 160ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c = 2; 161ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (op) { 162ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0: c = btsl_mem(block, bitoff); break; 163ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 1: c = btrl_mem(block, bitoff); break; 164ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 2: c = btcl_mem(block, bitoff); break; 165ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 3: c = btl_mem(block, bitoff); break; 166ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 167ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown assert(c == 0 || c == 1); 168ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown carrydep = c ? (rol1(carrydep) ^ bitoff) : carrydep; 169ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 170ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 171ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Compute final result */ 172ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown block -= 100; 173ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res = 0; 174ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (n = 0; n < 200; n++) { 175ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown UChar ch = block[n]; 176ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* printf("%d ", (int)block[n]); */ 177ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown res = rol1(res) ^ (UInt)ch; 178ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 179ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 180ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown printf("MEM-L: final res 0x%x, carrydep 0x%x\n", res, carrydep); 181ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 182ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /*------------------------ REG-L -----------------------*/ 183ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 184ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown carrydep = 0; 185ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown reg = 0; 186ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 187ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown for (n = 0; n < 1000; n++) { 188ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown bitoff = (random() % 100) - 50; 189ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown op = random() % 4; 190ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown c = 2; 191ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown switch (op) { 192ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 0: c = btsl_reg(reg, bitoff, ®); break; 193ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 1: c = btrl_reg(reg, bitoff, ®); break; 194ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 2: c = btcl_reg(reg, bitoff, ®); break; 195ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown case 3: c = btl_reg(reg, bitoff, ®); break; 196ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 197ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown assert(c == 0 || c == 1); 198ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown carrydep = c ? (rol1(carrydep) ^ bitoff) : carrydep; 199ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 200ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 201ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown printf("REG-L: final res 0x%x, carrydep 0x%x\n", reg, carrydep); 202ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 203ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown block += 100; 204ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 205ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown /* Just try one of these at once; more than one can cause a 206ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown confusing merging of error messages. */ 207ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown //btsl_mem(block, -800); /* should not complain */ 208ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown //btsl_mem(block, -801); /* should complain */ 209ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown //btsl_mem(block, 799); /* should not complain */ 210ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown //btsl_mem(block, 800); /* should complain */ 211ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 212ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown block -= 100; 213ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown free(block); 214ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 215ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0; 216ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 217ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 218