| |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <assert.h> |
| |
| typedef unsigned int UInt; |
| |
| /* Given a word, do bt/bts/btr/btc on bits 0, 1, 2 and 3 of it, and |
| also reconstruct the original bits 0, 1, 2, 3 by looking at the |
| carry flag. Returned result has mashed bits 0-3 at the bottom and |
| the reconstructed original bits 0-3 as 4-7. */ |
| UInt mash_reg_L ( UInt orig ) |
| { |
| UInt reconstructed, mashed; |
| __asm__ __volatile__ ( |
| "movl %2, %%edx\n\t" |
| "" |
| "movl $0, %%eax\n\t" |
| "\n\t" |
| "btl $0, %%edx\n\t" |
| "setb %%cl\n\t" |
| "movzbl %%cl, %%ecx\n\t" |
| "orl %%ecx, %%eax\n\t" |
| "\n\t" |
| "btsl $1, %%edx\n\t" |
| "setb %%cl\n\t" |
| "movzbl %%cl, %%ecx\n\t" |
| "shll $1, %%ecx\n\t" |
| "orl %%ecx, %%eax\n\t" |
| "\n\t" |
| "btrl $2, %%edx\n\t" |
| "setb %%cl\n\t" |
| "movzbl %%cl, %%ecx\n\t" |
| "shll $2, %%ecx\n\t" |
| "orl %%ecx, %%eax\n\t" |
| "\n\t" |
| "btcl $3, %%edx\n\t" |
| "setb %%cl\n\t" |
| "movzbl %%cl, %%ecx\n\t" |
| "shll $3, %%ecx\n\t" |
| "orl %%ecx, %%eax\n\t" |
| "\n\t" |
| "movl %%eax, %0\n\t" |
| "movl %%edx, %1" |
| |
| : "=r" (reconstructed), "=r" (mashed) |
| : "r" (orig) |
| : "eax", "ecx", "edx", "cc"); |
| return (mashed & 0xF) | ((reconstructed & 0xF) << 4); |
| } |
| |
| |
| |
| |
| UInt mash_mem_L ( UInt* origp ) |
| { |
| UInt reconstructed, mashed; |
| __asm__ __volatile__ ( |
| "movl %2, %%edx\n\t" |
| "" |
| "movl $0, %%eax\n\t" |
| "\n\t" |
| "btl $0, (%%edx)\n\t" |
| "setb %%cl\n\t" |
| "movzbl %%cl, %%ecx\n\t" |
| "orl %%ecx, %%eax\n\t" |
| "\n\t" |
| "btsl $1, (%%edx)\n\t" |
| "setb %%cl\n\t" |
| "movzbl %%cl, %%ecx\n\t" |
| "shll $1, %%ecx\n\t" |
| "orl %%ecx, %%eax\n\t" |
| "\n\t" |
| "btrl $2, (%%edx)\n\t" |
| "setb %%cl\n\t" |
| "movzbl %%cl, %%ecx\n\t" |
| "shll $2, %%ecx\n\t" |
| "orl %%ecx, %%eax\n\t" |
| "\n\t" |
| "btcl $3, (%%edx)\n\t" |
| "setb %%cl\n\t" |
| "movzbl %%cl, %%ecx\n\t" |
| "shll $3, %%ecx\n\t" |
| "orl %%ecx, %%eax\n\t" |
| "\n\t" |
| "movl %%eax, %0\n\t" |
| "movl (%%edx), %1" |
| |
| : "=r" (reconstructed), "=r" (mashed) |
| : "r" (origp) |
| : "eax", "ecx", "edx", "cc"); |
| return (mashed & 0xF) | ((reconstructed & 0xF) << 4); |
| } |
| |
| |
| |
| UInt mash_reg_W ( UInt orig ) |
| { |
| UInt reconstructed, mashed; |
| __asm__ __volatile__ ( |
| "movl %2, %%edx\n\t" |
| "" |
| "movl $0, %%eax\n\t" |
| "\n\t" |
| "btw $0, %%dx\n\t" |
| "setb %%cl\n\t" |
| "movzbl %%cl, %%ecx\n\t" |
| "orl %%ecx, %%eax\n\t" |
| "\n\t" |
| "btsw $1, %%dx\n\t" |
| "setb %%cl\n\t" |
| "movzbl %%cl, %%ecx\n\t" |
| "shll $1, %%ecx\n\t" |
| "orl %%ecx, %%eax\n\t" |
| "\n\t" |
| "btrw $2, %%dx\n\t" |
| "setb %%cl\n\t" |
| "movzbl %%cl, %%ecx\n\t" |
| "shll $2, %%ecx\n\t" |
| "orl %%ecx, %%eax\n\t" |
| "\n\t" |
| "btcw $3, %%dx\n\t" |
| "setb %%cl\n\t" |
| "movzbl %%cl, %%ecx\n\t" |
| "shll $3, %%ecx\n\t" |
| "orl %%ecx, %%eax\n\t" |
| "\n\t" |
| "movl %%eax, %0\n\t" |
| "movl %%edx, %1" |
| |
| : "=r" (reconstructed), "=r" (mashed) |
| : "r" (orig) |
| : "eax", "ecx", "edx", "cc"); |
| return (mashed & 0xF) | ((reconstructed & 0xF) << 4); |
| } |
| |
| |
| |
| |
| int main ( void ) |
| { |
| int i, ii; |
| for (i = 0; i < 0x10; i++) { |
| ii = i; |
| printf("0x%x -> 0x%2x 0x%2x 0x%2x\n", i, |
| mash_reg_L(i), mash_mem_L(&ii), mash_reg_W(i)); |
| } |
| return 1; |
| } |
| |