1 #include <stdio.h> 2 3 /* Dummy variable. Needed to work around GCC code generation bugs */ 4 volatile 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