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