blob: 3d8f84bffe7a60ca01b24af8491dbee201284bea [file] [log] [blame]
bellard379ca802003-02-24 23:43:02 +00001
2#define exec_op glue(exec_, OP)
bellard776f2222005-03-02 22:19:12 +00003#define exec_opq glue(glue(exec_, OP), q)
bellard379ca802003-02-24 23:43:02 +00004#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
bellardd57c4e02003-03-04 01:14:13 +00008#ifndef OP_SHIFTD
9
10#ifdef OP_NOBYTE
bellard776f2222005-03-02 22:19:12 +000011#define EXECSHIFT(size, rsize, res, s1, s2, flags) \
bellardd57c4e02003-03-04 01:14:13 +000012 asm ("push %4\n\t"\
13 "popf\n\t"\
bellard776f2222005-03-02 22:19:12 +000014 stringify(OP) size " %" rsize "2, %" rsize "0\n\t" \
bellardd57c4e02003-03-04 01:14:13 +000015 "pushf\n\t"\
bellard776f2222005-03-02 22:19:12 +000016 "pop %1\n\t"\
bellardd57c4e02003-03-04 01:14:13 +000017 : "=g" (res), "=g" (flags)\
18 : "r" (s1), "0" (res), "1" (flags));
19#else
bellard776f2222005-03-02 22:19:12 +000020#define EXECSHIFT(size, rsize, res, s1, s2, flags) \
bellard379ca802003-02-24 23:43:02 +000021 asm ("push %4\n\t"\
22 "popf\n\t"\
bellard776f2222005-03-02 22:19:12 +000023 stringify(OP) size " %%cl, %" rsize "0\n\t" \
bellard379ca802003-02-24 23:43:02 +000024 "pushf\n\t"\
bellard776f2222005-03-02 22:19:12 +000025 "pop %1\n\t"\
bellard379ca802003-02-24 23:43:02 +000026 : "=q" (res), "=g" (flags)\
27 : "c" (s1), "0" (res), "1" (flags));
bellardd57c4e02003-03-04 01:14:13 +000028#endif
bellard379ca802003-02-24 23:43:02 +000029
bellard776f2222005-03-02 22:19:12 +000030#if defined(__x86_64__)
31void exec_opq(long s2, long s0, long s1, long iflags)
bellard379ca802003-02-24 23:43:02 +000032{
bellard776f2222005-03-02 22:19:12 +000033 long res, flags;
bellard379ca802003-02-24 23:43:02 +000034 res = s0;
35 flags = iflags;
bellard776f2222005-03-02 22:19:12 +000036 EXECSHIFT("q", "", res, s1, s2, flags);
bellard379ca802003-02-24 23:43:02 +000037 /* overflow is undefined if count != 1 */
38 if (s1 != 1)
39 flags &= ~CC_O;
bellard776f2222005-03-02 22:19:12 +000040 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
45void 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",
bellard379ca802003-02-24 23:43:02 +000055 stringify(OP) "l", s0, s1, res, iflags, flags & CC_MASK);
56}
57
bellard776f2222005-03-02 22:19:12 +000058void exec_opw(long s2, long s0, long s1, long iflags)
bellard379ca802003-02-24 23:43:02 +000059{
bellard776f2222005-03-02 22:19:12 +000060 long res, flags;
bellard379ca802003-02-24 23:43:02 +000061 res = s0;
62 flags = iflags;
bellard776f2222005-03-02 22:19:12 +000063 EXECSHIFT("w", "w", res, s1, s2, flags);
bellard379ca802003-02-24 23:43:02 +000064 /* overflow is undefined if count != 1 */
65 if (s1 != 1)
66 flags &= ~CC_O;
bellard776f2222005-03-02 22:19:12 +000067 printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n",
bellard379ca802003-02-24 23:43:02 +000068 stringify(OP) "w", s0, s1, res, iflags, flags & CC_MASK);
69}
70
bellardd57c4e02003-03-04 01:14:13 +000071#else
bellard776f2222005-03-02 22:19:12 +000072#define EXECSHIFT(size, rsize, res, s1, s2, flags) \
bellardd57c4e02003-03-04 01:14:13 +000073 asm ("push %4\n\t"\
74 "popf\n\t"\
bellard776f2222005-03-02 22:19:12 +000075 stringify(OP) size " %%cl, %" rsize "5, %" rsize "0\n\t" \
bellardd57c4e02003-03-04 01:14:13 +000076 "pushf\n\t"\
bellard776f2222005-03-02 22:19:12 +000077 "pop %1\n\t"\
bellardd57c4e02003-03-04 01:14:13 +000078 : "=g" (res), "=g" (flags)\
79 : "c" (s1), "0" (res), "1" (flags), "r" (s2));
80
bellard776f2222005-03-02 22:19:12 +000081#if defined(__x86_64__)
82void exec_opq(long s2, long s0, long s1, long iflags)
bellardd57c4e02003-03-04 01:14:13 +000083{
bellard776f2222005-03-02 22:19:12 +000084 long res, flags;
bellardd57c4e02003-03-04 01:14:13 +000085 res = s0;
86 flags = iflags;
bellard776f2222005-03-02 22:19:12 +000087 EXECSHIFT("q", "", res, s1, s2, flags);
bellardd57c4e02003-03-04 01:14:13 +000088 /* overflow is undefined if count != 1 */
89 if (s1 != 1)
90 flags &= ~CC_O;
bellard776f2222005-03-02 22:19:12 +000091 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
96void 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",
bellardd57c4e02003-03-04 01:14:13 +0000106 stringify(OP) "l", s0, s2, s1, res, iflags, flags & CC_MASK);
107}
108
bellard776f2222005-03-02 22:19:12 +0000109void exec_opw(long s2, long s0, long s1, long iflags)
bellardd57c4e02003-03-04 01:14:13 +0000110{
bellard776f2222005-03-02 22:19:12 +0000111 long res, flags;
bellardd57c4e02003-03-04 01:14:13 +0000112 res = s0;
113 flags = iflags;
bellard776f2222005-03-02 22:19:12 +0000114 EXECSHIFT("w", "w", res, s1, s2, flags);
bellardd57c4e02003-03-04 01:14:13 +0000115 /* overflow is undefined if count != 1 */
116 if (s1 != 1)
117 flags &= ~CC_O;
bellard776f2222005-03-02 22:19:12 +0000118 printf("%-10s A=" FMTLX " B=" FMTLX " C=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n",
bellardd57c4e02003-03-04 01:14:13 +0000119 stringify(OP) "w", s0, s2, s1, res, iflags, flags & CC_MASK);
120}
121
122#endif
123
124#ifndef OP_NOBYTE
bellard776f2222005-03-02 22:19:12 +0000125void exec_opb(long s0, long s1, long iflags)
bellard379ca802003-02-24 23:43:02 +0000126{
bellard776f2222005-03-02 22:19:12 +0000127 long res, flags;
bellard379ca802003-02-24 23:43:02 +0000128 res = s0;
129 flags = iflags;
bellard776f2222005-03-02 22:19:12 +0000130 EXECSHIFT("b", "b", res, s1, 0, flags);
bellard379ca802003-02-24 23:43:02 +0000131 /* overflow is undefined if count != 1 */
132 if (s1 != 1)
133 flags &= ~CC_O;
bellard776f2222005-03-02 22:19:12 +0000134 printf("%-10s A=" FMTLX " B=" FMTLX " R=" FMTLX " CCIN=%04lx CC=%04lx\n",
bellard379ca802003-02-24 23:43:02 +0000135 stringify(OP) "b", s0, s1, res, iflags, flags & CC_MASK);
136}
bellardd57c4e02003-03-04 01:14:13 +0000137#endif
bellard379ca802003-02-24 23:43:02 +0000138
bellard776f2222005-03-02 22:19:12 +0000139void exec_op(long s2, long s0, long s1)
bellard379ca802003-02-24 23:43:02 +0000140{
bellard776f2222005-03-02 22:19:12 +0000141 s2 = i2l(s2);
142 s0 = i2l(s0);
143#if defined(__x86_64__)
144 exec_opq(s2, s0, s1, 0);
145#endif
bellardd57c4e02003-03-04 01:14:13 +0000146 exec_opl(s2, s0, s1, 0);
bellardafeb6ee2003-04-11 00:12:54 +0000147#ifdef OP_SHIFTD
bellarda5973fb2008-05-28 12:34:49 +0000148 exec_opw(s2, s0, s1, 0);
bellardafeb6ee2003-04-11 00:12:54 +0000149#else
bellardd57c4e02003-03-04 01:14:13 +0000150 exec_opw(s2, s0, s1, 0);
bellardafeb6ee2003-04-11 00:12:54 +0000151#endif
bellardd57c4e02003-03-04 01:14:13 +0000152#ifndef OP_NOBYTE
bellard379ca802003-02-24 23:43:02 +0000153 exec_opb(s0, s1, 0);
bellardd57c4e02003-03-04 01:14:13 +0000154#endif
bellard379ca802003-02-24 23:43:02 +0000155#ifdef OP_CC
bellard776f2222005-03-02 22:19:12 +0000156#if defined(__x86_64__)
157 exec_opq(s2, s0, s1, CC_C);
158#endif
bellardd57c4e02003-03-04 01:14:13 +0000159 exec_opl(s2, s0, s1, CC_C);
160 exec_opw(s2, s0, s1, CC_C);
bellard379ca802003-02-24 23:43:02 +0000161 exec_opb(s0, s1, CC_C);
162#endif
163}
164
165void glue(test_, OP)(void)
166{
bellard776f2222005-03-02 22:19:12 +0000167 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++)
bellardd57c4e02003-03-04 01:14:13 +0000174 exec_op(0x21ad3d34, 0x12345678, i);
bellard776f2222005-03-02 22:19:12 +0000175 for(i = 0; i < n; i++)
bellard6c3ee142006-04-24 20:18:26 +0000176 exec_op(0x813f3421, 0x82345679, i);
bellard379ca802003-02-24 23:43:02 +0000177}
178
179void *glue(_test_, OP) __init_call = glue(test_, OP);
180
181#undef OP
182#undef OP_CC
bellardd57c4e02003-03-04 01:14:13 +0000183#undef OP_SHIFTD
184#undef OP_NOBYTE
185#undef EXECSHIFT