1#include <stdio.h> 2 3/* Dummy variable. Needed to work around GCC code generation bugs */ 4volatile long v; 5 6#define AND_REG_MEM(insn, s1, s2) \ 7({ \ 8 unsigned long tmp = s1; \ 9 int cc; \ 10 asm volatile( #insn " %0, %3\n" \ 11 "ipm %1\n" \ 12 "srl %1,28\n" \ 13 : "+d" (tmp), "=d" (cc) \ 14 : "d" (tmp), "Q" (s2) \ 15 : "0", "cc"); \ 16 printf(#insn " + %16.16lX & %16.16lX = %16.16lX (cc=%d)\n", s1, s2, tmp, cc); \ 17}) 18 19#define AND_REG_REG(insn, s1, s2) \ 20({ \ 21 unsigned long tmp = s1; \ 22 int cc; \ 23 asm volatile( #insn " %0, %3\n" \ 24 "ipm %1\n" \ 25 "srl %1,28\n" \ 26 : "+d" (tmp), "=d" (cc) \ 27 : "d" (tmp), "d" (s2) \ 28 : "0", "cc"); \ 29 printf(#insn " + %16.16lX & %16.16lX = %16.16lX (cc=%d)\n", s1, s2, tmp, cc); \ 30}) 31 32#define AND_REG_IMM(insn, s1, s2) \ 33({ \ 34 register unsigned long tmp asm("2") = s1; \ 35 int cc; \ 36 asm volatile( insn(2,s2) \ 37 "ipm %1\n" \ 38 "srl %1,28\n" \ 39 : "+d" (tmp), "=d" (cc) \ 40 : "d" (tmp) \ 41 : "cc"); \ 42 v = tmp; /* work around GCC code gen bug */ \ 43 printf(#insn " + %16.16lX & %16.16lX = %16.16lX (cc=%d)\n", s1, (unsigned long) 0x##s2, v, cc); \ 44}) 45 46#define AND_MEM_IMM(insn, s1, s2) \ 47({ \ 48 unsigned long tmp = s1; \ 49 int cc; \ 50 asm volatile( #insn " %0," #s2 "\n" \ 51 "ipm %1\n" \ 52 "srl %1,28\n" \ 53 : "+Q" (tmp), "=d" (cc) \ 54 : "Q" (tmp) \ 55 : "0", "cc"); \ 56 printf(#insn " + %16.16lX & %16.16lX = %16.16lX (cc=%d)\n", s1, (unsigned long) s2, tmp, cc); \ 57}) 58 59 60#define memsweep(i, s2) \ 61({ \ 62 AND_REG_MEM(i, 0ul, s2); \ 63 AND_REG_MEM(i, 1ul, s2); \ 64 AND_REG_MEM(i, 0xfffful, s2); \ 65 AND_REG_MEM(i, 0x7ffful, s2); \ 66 AND_REG_MEM(i, 0x8000ul, s2); \ 67 AND_REG_MEM(i, 0xfffffffful, s2); \ 68 AND_REG_MEM(i, 0x80000000ul, s2); \ 69 AND_REG_MEM(i, 0x7ffffffful, s2); \ 70 AND_REG_MEM(i, 0xaaaaaaaaaaaaaaaaul, s2); \ 71 AND_REG_MEM(i, 0x8000000000000000ul, s2); \ 72 AND_REG_MEM(i, 0xfffffffffffffffful, s2); \ 73 AND_REG_MEM(i, 0x5555555555555555ul, s2); \ 74}) 75 76#define regsweep(i, s2) \ 77({ \ 78 AND_REG_REG(i, 0ul, s2); \ 79 AND_REG_REG(i, 1ul, s2); \ 80 AND_REG_REG(i, 0xfffful, s2); \ 81 AND_REG_REG(i, 0x7ffful, s2); \ 82 AND_REG_REG(i, 0x8000ul, s2); \ 83 AND_REG_REG(i, 0xfffffffful, s2); \ 84 AND_REG_REG(i, 0x80000000ul, s2); \ 85 AND_REG_REG(i, 0x7ffffffful, s2); \ 86 AND_REG_REG(i, 0xaaaaaaaaaaaaaaaaul, s2); \ 87 AND_REG_REG(i, 0x8000000000000000ul, s2); \ 88 AND_REG_REG(i, 0xfffffffffffffffful, s2); \ 89 AND_REG_REG(i, 0x5555555555555555ul, s2); \ 90}) 91 92#define immsweep(i, s2) \ 93({ \ 94 AND_REG_IMM(i, 0ul, s2); \ 95 AND_REG_IMM(i, 1ul, s2); \ 96 AND_REG_IMM(i, 0xfffful, s2); \ 97 AND_REG_IMM(i, 0x7ffful, s2); \ 98 AND_REG_IMM(i, 0x8000ul, s2); \ 99 AND_REG_IMM(i, 0xfffffffful, s2); \ 100 AND_REG_IMM(i, 0x80000000ul, s2); \ 101 AND_REG_IMM(i, 0x7ffffffful, s2); \ 102 AND_REG_IMM(i, 0xaaaaaaaaaaaaaaaaul, s2); \ 103 AND_REG_IMM(i, 0x8000000000000000ul, s2); \ 104 AND_REG_IMM(i, 0xfffffffffffffffful, s2); \ 105 AND_REG_IMM(i, 0x5555555555555555ul, s2); \ 106}) 107 108#define memimmsweep(i, s2) \ 109({ \ 110 AND_MEM_IMM(i, 0ul, s2); \ 111 AND_MEM_IMM(i, 1ul, s2); \ 112 AND_MEM_IMM(i, 0xfffful, s2); \ 113 AND_MEM_IMM(i, 0x7ffful, s2); \ 114 AND_MEM_IMM(i, 0x8000ul, s2); \ 115 AND_MEM_IMM(i, 0xfffffffful, s2); \ 116 AND_MEM_IMM(i, 0x80000000ul, s2); \ 117 AND_MEM_IMM(i, 0x7ffffffful, s2); \ 118 AND_MEM_IMM(i, 0xaaaaaaaaaaaaaaaaul, s2); \ 119 AND_MEM_IMM(i, 0x8000000000000000ul, s2); \ 120 AND_MEM_IMM(i, 0xfffffffffffffffful, s2); \ 121 AND_MEM_IMM(i, 0x5555555555555555ul, s2); \ 122}) 123 124#define AND_NY(s1, s2) \ 125({ \ 126 register unsigned long tmp asm("1") = s1; \ 127 register unsigned long *addr asm("2") = &s2; \ 128 int cc; \ 129 asm volatile( NY(1,0,2,000,00) \ 130 "ipm %1\n" \ 131 "srl %1,28\n" \ 132 : "+d" (tmp), "=d" (cc) \ 133 : "d" (tmp), "d"(addr) \ 134 : "cc"); \ 135 printf("ny + %16.16lX & %16.16lX = %16.16lX (cc=%d)\n", s1, s2, tmp, cc); \ 136}) 137 138#define AND_NIY(s1, i2) \ 139({ \ 140 unsigned long tmp = s1; \ 141 register unsigned long *addr asm("2") = &tmp; \ 142 int cc; \ 143 asm volatile( NIY(i2,2,000,00) \ 144 "ipm %1\n" \ 145 "srl %1,28\n" \ 146 : "+Q" (tmp), "=d" (cc) \ 147 : "Q" (tmp), "d" (addr) \ 148 : "cc"); \ 149 printf("niy + %16.16lX & %16.16lX = %16.16lX (cc=%d)\n", s1, (unsigned long) 0x##i2, tmp, cc); \ 150}) 151 152#define nysweep(s2) \ 153({ \ 154 AND_NY(0ul, s2); \ 155 AND_NY(1ul, s2); \ 156 AND_NY(0xfffful, s2); \ 157 AND_NY(0x7ffful, s2); \ 158 AND_NY(0x8000ul, s2); \ 159 AND_NY(0xfffffffful, s2); \ 160 AND_NY(0x80000000ul, s2); \ 161 AND_NY(0x7ffffffful, s2); \ 162 AND_NY(0xaaaaaaaaaaaaaaaaul, s2); \ 163 AND_NY(0x8000000000000000ul, s2); \ 164 AND_NY(0xfffffffffffffffful, s2); \ 165 AND_NY(0x5555555555555555ul, s2); \ 166}) 167 168#define niysweep(s2) \ 169({ \ 170 AND_NIY(0ul, s2); \ 171 AND_NIY(1ul, s2); \ 172 AND_NIY(0xfffful, s2); \ 173 AND_NIY(0x7ffful, s2); \ 174 AND_NIY(0x8000ul, s2); \ 175 AND_NIY(0xfffffffful, s2); \ 176 AND_NIY(0x80000000ul, s2); \ 177 AND_NIY(0x7ffffffful, s2); \ 178 AND_NIY(0xaaaaaaaaaaaaaaaaul, s2); \ 179 AND_NIY(0x8000000000000000ul, s2); \ 180 AND_NIY(0xfffffffffffffffful, s2); \ 181 AND_NIY(0x5555555555555555ul, s2); \ 182}) 183