1 2 #define exec_op glue(exec_, OP) 3 #define exec_opq glue(glue(exec_, OP), q) 4 #define exec_opl glue(glue(exec_, OP), l) 5 #define exec_opw glue(glue(exec_, OP), w) 6 #define exec_opb glue(glue(exec_, OP), b) 7 8 #ifndef OP_SHIFTD 9 10 #ifdef OP_NOBYTE 11 #define EXECSHIFT(size, rsize, res, s1, s2, flags) \ 12 asm ("push %4\n\t"\ 13 "popf\n\t"\ 14 stringify(OP) size " %" rsize "2, %" rsize "0\n\t" \ 15 "pushf\n\t"\ 16 "pop %1\n\t"\ 17 : "=g" (res), "=g" (flags)\ 18 : "r" (s1), "0" (res), "1" (flags)); 19 #else 20 #define EXECSHIFT(size, rsize, res, s1, s2, flags) \ 21 asm ("push %4\n\t"\ 22 "popf\n\t"\ 23 stringify(OP) size " %%cl, %" rsize "0\n\t" \ 24 "pushf\n\t"\ 25 "pop %1\n\t"\ 26 : "=q" (res), "=g" (flags)\ 27 : "c" (s1), "0" (res), "1" (flags)); 28 #endif 29 30 #if defined(__x86_64__) 31 void exec_opq(long s2, long s0, long s1, long iflags) 32 { 33 long res, flags; 34 res = s0; 35 flags = iflags; 36 EXECSHIFT("q", "", res, s1, s2, flags); 37 /* overflow is undefined if count != 1 */ 38 if (s1 != 1) 39 flags &= ~CC_O; 40 printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n", 41 stringify(OP) "q", s0, s1, res, iflags, flags & CC_MASK); 42 } 43 #endif 44 45 void exec_opl(long s2, long s0, long s1, long iflags) 46 { 47 long res, flags; 48 res = s0; 49 flags = iflags; 50 EXECSHIFT("l", "k", res, s1, s2, flags); 51 /* overflow is undefined if count != 1 */ 52 if (s1 != 1) 53 flags &= ~CC_O; 54 printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n", 55 stringify(OP) "l", s0, s1, res, iflags, flags & CC_MASK); 56 } 57 58 void exec_opw(long s2, long s0, long s1, long iflags) 59 { 60 long res, flags; 61 res = s0; 62 flags = iflags; 63 EXECSHIFT("w", "w", res, s1, s2, flags); 64 /* overflow is undefined if count != 1 */ 65 if (s1 != 1) 66 flags &= ~CC_O; 67 printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n", 68 stringify(OP) "w", s0, s1, res, iflags, flags & CC_MASK); 69 } 70 71 #else 72 #define EXECSHIFT(size, rsize, res, s1, s2, flags) \ 73 asm ("push %4\n\t"\ 74 "popf\n\t"\ 75 stringify(OP) size " %%cl, %" rsize "5, %" rsize "0\n\t" \ 76 "pushf\n\t"\ 77 "pop %1\n\t"\ 78 : "=g" (res), "=g" (flags)\ 79 : "c" (s1), "0" (res), "1" (flags), "r" (s2)); 80 81 #if defined(__x86_64__) 82 void exec_opq(long s2, long s0, long s1, long iflags) 83 { 84 long res, flags; 85 res = s0; 86 flags = iflags; 87 EXECSHIFT("q", "", res, s1, s2, flags); 88 /* overflow is undefined if count != 1 */ 89 if (s1 != 1) 90 flags &= ~CC_O; 91 printf("%-10s A=" FMTLX " B=" FMTLX " C=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n", 92 stringify(OP) "q", s0, s2, s1, res, iflags, flags & CC_MASK); 93 } 94 #endif 95 96 void exec_opl(long s2, long s0, long s1, long iflags) 97 { 98 long res, flags; 99 res = s0; 100 flags = iflags; 101 EXECSHIFT("l", "k", res, s1, s2, flags); 102 /* overflow is undefined if count != 1 */ 103 if (s1 != 1) 104 flags &= ~CC_O; 105 printf("%-10s A=" FMTLX " B=" FMTLX " C=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n", 106 stringify(OP) "l", s0, s2, s1, res, iflags, flags & CC_MASK); 107 } 108 109 void exec_opw(long s2, long s0, long s1, long iflags) 110 { 111 long res, flags; 112 res = s0; 113 flags = iflags; 114 EXECSHIFT("w", "w", res, s1, s2, flags); 115 /* overflow is undefined if count != 1 */ 116 if (s1 != 1) 117 flags &= ~CC_O; 118 printf("%-10s A=" FMTLX " B=" FMTLX " C=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n", 119 stringify(OP) "w", s0, s2, s1, res, iflags, flags & CC_MASK); 120 } 121 122 #endif 123 124 #ifndef OP_NOBYTE 125 void exec_opb(long s0, long s1, long iflags) 126 { 127 long res, flags; 128 res = s0; 129 flags = iflags; 130 EXECSHIFT("b", "b", res, s1, 0, flags); 131 /* overflow is undefined if count != 1 */ 132 if (s1 != 1) 133 flags &= ~CC_O; 134 printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n", 135 stringify(OP) "b", s0, s1, res, iflags, flags & CC_MASK); 136 } 137 #endif 138 139 void exec_op(long s2, long s0, long s1) 140 { 141 s2 = i2l(s2); 142 s0 = i2l(s0); 143 #if defined(__x86_64__) 144 exec_opq(s2, s0, s1, 0); 145 #endif 146 exec_opl(s2, s0, s1, 0); 147 #ifdef OP_SHIFTD 148 exec_opw(s2, s0, s1, 0); 149 #else 150 exec_opw(s2, s0, s1, 0); 151 #endif 152 #ifndef OP_NOBYTE 153 exec_opb(s0, s1, 0); 154 #endif 155 #ifdef OP_CC 156 #if defined(__x86_64__) 157 exec_opq(s2, s0, s1, CC_C); 158 #endif 159 exec_opl(s2, s0, s1, CC_C); 160 exec_opw(s2, s0, s1, CC_C); 161 exec_opb(s0, s1, CC_C); 162 #endif 163 } 164 165 void glue(test_, OP)(void) 166 { 167 int i, n; 168 #if defined(__x86_64__) 169 n = 64; 170 #else 171 n = 32; 172 #endif 173 for(i = 0; i < n; i++) 174 exec_op(0x21ad3d34, 0x12345678, i); 175 for(i = 0; i < n; i++) 176 exec_op(0x813f3421, 0x82345679, i); 177 } 178 179 void *glue(_test_, OP) __init_call = glue(test_, OP); 180 181 #undef OP 182 #undef OP_CC 183 #undef OP_SHIFTD 184 #undef OP_NOBYTE 185 #undef EXECSHIFT 186