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 30void 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 43void 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 56void 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 79void 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 92void 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 108void 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 122void 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 162void 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 171void *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