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