xref: /openbmc/qemu/tests/tcg/i386/test-i386-shift.h (revision b14df228)
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