00001
00002 #define exec_op glue(exec_, OP)
00003 #define exec_opq glue(glue(exec_, OP), q)
00004 #define exec_opl glue(glue(exec_, OP), l)
00005 #define exec_opw glue(glue(exec_, OP), w)
00006 #define exec_opb glue(glue(exec_, OP), b)
00007
00008 #ifndef OP_SHIFTD
00009
00010 #ifdef OP_NOBYTE
00011 #define EXECSHIFT(size, rsize, res, s1, s2, flags) \
00012 asm ("push %4\n\t"\
00013 "popf\n\t"\
00014 stringify(OP) size " %" rsize "2, %" rsize "0\n\t" \
00015 "pushf\n\t"\
00016 "pop %1\n\t"\
00017 : "=g" (res), "=g" (flags)\
00018 : "r" (s1), "0" (res), "1" (flags));
00019 #else
00020 #define EXECSHIFT(size, rsize, res, s1, s2, flags) \
00021 asm ("push %4\n\t"\
00022 "popf\n\t"\
00023 stringify(OP) size " %%cl, %" rsize "0\n\t" \
00024 "pushf\n\t"\
00025 "pop %1\n\t"\
00026 : "=q" (res), "=g" (flags)\
00027 : "c" (s1), "0" (res), "1" (flags));
00028 #endif
00029
00030 #if defined(__x86_64__)
00031 void exec_opq(long s2, long s0, long s1, long iflags)
00032 {
00033 long res, flags;
00034 res = s0;
00035 flags = iflags;
00036 EXECSHIFT("q", "", res, s1, s2, flags);
00037
00038 if (s1 != 1)
00039 flags &= ~CC_O;
00040 printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n",
00041 stringify(OP) "q", s0, s1, res, iflags, flags & CC_MASK);
00042 }
00043 #endif
00044
00045 void exec_opl(long s2, long s0, long s1, long iflags)
00046 {
00047 long res, flags;
00048 res = s0;
00049 flags = iflags;
00050 EXECSHIFT("l", "k", res, s1, s2, flags);
00051
00052 if (s1 != 1)
00053 flags &= ~CC_O;
00054 printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n",
00055 stringify(OP) "l", s0, s1, res, iflags, flags & CC_MASK);
00056 }
00057
00058 void exec_opw(long s2, long s0, long s1, long iflags)
00059 {
00060 long res, flags;
00061 res = s0;
00062 flags = iflags;
00063 EXECSHIFT("w", "w", res, s1, s2, flags);
00064
00065 if (s1 != 1)
00066 flags &= ~CC_O;
00067 printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n",
00068 stringify(OP) "w", s0, s1, res, iflags, flags & CC_MASK);
00069 }
00070
00071 #else
00072 #define EXECSHIFT(size, rsize, res, s1, s2, flags) \
00073 asm ("push %4\n\t"\
00074 "popf\n\t"\
00075 stringify(OP) size " %%cl, %" rsize "5, %" rsize "0\n\t" \
00076 "pushf\n\t"\
00077 "pop %1\n\t"\
00078 : "=g" (res), "=g" (flags)\
00079 : "c" (s1), "0" (res), "1" (flags), "r" (s2));
00080
00081 #if defined(__x86_64__)
00082 void exec_opq(long s2, long s0, long s1, long iflags)
00083 {
00084 long res, flags;
00085 res = s0;
00086 flags = iflags;
00087 EXECSHIFT("q", "", res, s1, s2, flags);
00088
00089 if (s1 != 1)
00090 flags &= ~CC_O;
00091 printf("%-10s A=" FMTLX " B=" FMTLX " C=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n",
00092 stringify(OP) "q", s0, s2, s1, res, iflags, flags & CC_MASK);
00093 }
00094 #endif
00095
00096 void exec_opl(long s2, long s0, long s1, long iflags)
00097 {
00098 long res, flags;
00099 res = s0;
00100 flags = iflags;
00101 EXECSHIFT("l", "k", res, s1, s2, flags);
00102
00103 if (s1 != 1)
00104 flags &= ~CC_O;
00105 printf("%-10s A=" FMTLX " B=" FMTLX " C=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n",
00106 stringify(OP) "l", s0, s2, s1, res, iflags, flags & CC_MASK);
00107 }
00108
00109 void exec_opw(long s2, long s0, long s1, long iflags)
00110 {
00111 long res, flags;
00112 res = s0;
00113 flags = iflags;
00114 EXECSHIFT("w", "w", res, s1, s2, flags);
00115
00116 if (s1 != 1)
00117 flags &= ~CC_O;
00118 printf("%-10s A=" FMTLX " B=" FMTLX " C=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n",
00119 stringify(OP) "w", s0, s2, s1, res, iflags, flags & CC_MASK);
00120 }
00121
00122 #endif
00123
00124 #ifndef OP_NOBYTE
00125 void exec_opb(long s0, long s1, long iflags)
00126 {
00127 long res, flags;
00128 res = s0;
00129 flags = iflags;
00130 EXECSHIFT("b", "b", res, s1, 0, flags);
00131
00132 if (s1 != 1)
00133 flags &= ~CC_O;
00134 printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n",
00135 stringify(OP) "b", s0, s1, res, iflags, flags & CC_MASK);
00136 }
00137 #endif
00138
00139 void exec_op(long s2, long s0, long s1)
00140 {
00141 s2 = i2l(s2);
00142 s0 = i2l(s0);
00143 #if defined(__x86_64__)
00144 exec_opq(s2, s0, s1, 0);
00145 #endif
00146 exec_opl(s2, s0, s1, 0);
00147 #ifdef OP_SHIFTD
00148 exec_opw(s2, s0, s1, 0);
00149 #else
00150 exec_opw(s2, s0, s1, 0);
00151 #endif
00152 #ifndef OP_NOBYTE
00153 exec_opb(s0, s1, 0);
00154 #endif
00155 #ifdef OP_CC
00156 #if defined(__x86_64__)
00157 exec_opq(s2, s0, s1, CC_C);
00158 #endif
00159 exec_opl(s2, s0, s1, CC_C);
00160 exec_opw(s2, s0, s1, CC_C);
00161 exec_opb(s0, s1, CC_C);
00162 #endif
00163 }
00164
00165 void glue(test_, OP)(void)
00166 {
00167 int i, n;
00168 #if defined(__x86_64__)
00169 n = 64;
00170 #else
00171 n = 32;
00172 #endif
00173 for(i = 0; i < n; i++)
00174 exec_op(0x21ad3d34, 0x12345678, i);
00175 for(i = 0; i < n; i++)
00176 exec_op(0x813f3421, 0x82345679, i);
00177 }
00178
00179 void *glue(_test_, OP) __init_call = glue(test_, OP);
00180
00181 #undef OP
00182 #undef OP_CC
00183 #undef OP_SHIFTD
00184 #undef OP_NOBYTE
00185 #undef EXECSHIFT