1 //===- subzero/unittest/AssemblerX8632/ControleFlow.cpp -------------------===//
2 //
3 // The Subzero Code Generator
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 #include "IceAssemblerX8632.h"
10 #include "AssemblerX8632/TestUtil.h"
11
12 namespace Ice {
13 namespace X8632 {
14 namespace Test {
15 namespace {
16
TEST_F(AssemblerX8632Test,J)17 TEST_F(AssemblerX8632Test, J) {
18 #define TestJ(C, Near, Src0, Value0, Src1, Value1, Dest) \
19 do { \
20 const bool NearJmp = AssemblerX8632::k##Near##Jump; \
21 Label ShouldBeTaken; \
22 __ mov(IceType_i32, GPRRegister::Encoded_Reg_##Src0, Immediate(Value0)); \
23 __ mov(IceType_i32, GPRRegister::Encoded_Reg_##Src1, Immediate(Value1)); \
24 __ mov(IceType_i32, GPRRegister::Encoded_Reg_##Dest, Immediate(0xBEEF)); \
25 __ cmp(IceType_i32, GPRRegister::Encoded_Reg_##Src0, \
26 GPRRegister::Encoded_Reg_##Src1); \
27 __ j(Cond::Br_##C, &ShouldBeTaken, NearJmp); \
28 __ mov(IceType_i32, GPRRegister::Encoded_Reg_##Dest, Immediate(0xC0FFEE)); \
29 __ bind(&ShouldBeTaken); \
30 AssembledTest test = assemble(); \
31 test.run(); \
32 EXPECT_EQ(Value0, test.Src0()) << "Br_" #C ", " #Near; \
33 EXPECT_EQ(Value1, test.Src1()) << "Br_" #C ", " #Near; \
34 EXPECT_EQ(0xBEEFul, test.Dest()) << "Br_" #C ", " #Near; \
35 reset(); \
36 } while (0)
37
38 TestJ(o, Near, eax, 0x80000000ul, ebx, 0x1ul, ecx);
39 TestJ(o, Far, ebx, 0x80000000ul, ecx, 0x1ul, edx);
40 TestJ(no, Near, ecx, 0x1ul, edx, 0x1ul, edi);
41 TestJ(no, Far, edx, 0x1ul, edi, 0x1ul, esi);
42 TestJ(b, Near, edi, 0x1ul, esi, 0x80000000ul, eax);
43 TestJ(b, Far, esi, 0x1ul, eax, 0x80000000ul, ebx);
44 TestJ(ae, Near, eax, 0x80000000ul, ebx, 0x1ul, ecx);
45 TestJ(ae, Far, ebx, 0x80000000ul, ecx, 0x1ul, edx);
46 TestJ(e, Near, ecx, 0x80000000ul, edx, 0x80000000ul, edi);
47 TestJ(e, Far, edx, 0x80000000ul, edi, 0x80000000ul, esi);
48 TestJ(ne, Near, edi, 0x80000000ul, esi, 0x1ul, eax);
49 TestJ(ne, Far, esi, 0x80000000ul, eax, 0x1ul, ebx);
50 TestJ(be, Near, eax, 0x1ul, ebx, 0x80000000ul, ecx);
51 TestJ(be, Far, ebx, 0x1ul, ecx, 0x80000000ul, edx);
52 TestJ(a, Near, ecx, 0x80000000ul, edx, 0x1ul, edi);
53 TestJ(a, Far, edx, 0x80000000ul, edi, 0x1ul, esi);
54 TestJ(s, Near, edi, 0x1ul, esi, 0x80000000ul, eax);
55 TestJ(s, Far, esi, 0x1ul, eax, 0x80000000ul, ebx);
56 TestJ(ns, Near, eax, 0x80000000ul, ebx, 0x1ul, ecx);
57 TestJ(ns, Far, ebx, 0x80000000ul, ecx, 0x1ul, edx);
58 TestJ(p, Near, ecx, 0x80000000ul, edx, 0x1ul, edi);
59 TestJ(p, Far, edx, 0x80000000ul, edi, 0x1ul, esi);
60 TestJ(np, Near, edi, 0x1ul, esi, 0x80000000ul, eax);
61 TestJ(np, Far, esi, 0x1ul, eax, 0x80000000ul, ebx);
62 TestJ(l, Near, eax, 0x80000000ul, ebx, 0x1ul, ecx);
63 TestJ(l, Far, ebx, 0x80000000ul, ecx, 0x1ul, edx);
64 TestJ(ge, Near, ecx, 0x1ul, edx, 0x80000000ul, edi);
65 TestJ(ge, Far, edx, 0x1ul, edi, 0x80000000ul, esi);
66 TestJ(le, Near, edi, 0x80000000ul, esi, 0x1ul, eax);
67 TestJ(le, Far, esi, 0x80000000ul, eax, 0x1ul, ebx);
68 TestJ(g, Near, eax, 0x1ul, ebx, 0x80000000ul, ecx);
69 TestJ(g, Far, ebx, 0x1ul, ecx, 0x80000000ul, edx);
70
71 #undef TestJ
72 }
73
TEST_F(AssemblerX8632Test,CallImm)74 TEST_F(AssemblerX8632Test, CallImm) {
75 __ call(Immediate(16));
76 __ hlt();
77 __ hlt();
78 __ hlt();
79 __ hlt();
80 __ hlt();
81 __ hlt();
82 __ hlt();
83 __ hlt();
84 __ hlt();
85 __ hlt();
86 __ hlt();
87 __ hlt();
88 __ mov(IceType_i32, GPRRegister::Encoded_Reg_eax, Immediate(0xf00f));
89 __ popl(GPRRegister::Encoded_Reg_ebx);
90
91 AssembledTest test = assemble();
92
93 test.run();
94
95 EXPECT_EQ(0xF00Fu, test.eax());
96 }
97
TEST_F(AssemblerX8632Test,CallReg)98 TEST_F(AssemblerX8632Test, CallReg) {
99 __ call(Immediate(16));
100 __ popl(GPRRegister::Encoded_Reg_edx);
101 __ pushl(GPRRegister::Encoded_Reg_edx);
102 __ ret();
103 __ hlt();
104 __ hlt();
105 __ hlt();
106 __ hlt();
107 __ hlt();
108 __ hlt();
109 __ hlt();
110 __ hlt();
111 __ hlt();
112 __ popl(GPRRegister::Encoded_Reg_ebx);
113 __ call(GPRRegister::Encoded_Reg_ebx);
114
115 AssembledTest test = assemble();
116
117 test.run();
118
119 EXPECT_EQ(15u, test.edx() - test.ebx());
120 }
121
TEST_F(AssemblerX8632Test,CallAddr)122 TEST_F(AssemblerX8632Test, CallAddr) {
123 __ call(Immediate(16));
124 __ mov(IceType_i8, GPRRegister::Encoded_Reg_eax, Immediate(0xf4));
125 __ ret();
126 __ hlt();
127 __ hlt();
128 __ hlt();
129 __ hlt();
130 __ hlt();
131 __ hlt();
132 __ hlt();
133 __ hlt();
134 __ hlt();
135 __ mov(IceType_i32, GPRRegister::Encoded_Reg_eax, Immediate(0xf1f2f300));
136 __ call(Address(GPRRegister::Encoded_Reg_esp, 0, AssemblerFixup::NoFixup));
137 __ popl(GPRRegister::Encoded_Reg_edx);
138
139 AssembledTest test = assemble();
140
141 test.run();
142
143 EXPECT_EQ(0xf1f2f3f4, test.eax());
144 }
145
TEST_F(AssemblerX8632Test,Jmp)146 TEST_F(AssemblerX8632Test, Jmp) {
147 // TestImplReg uses jmp(Label), so jmp(Label) needs to be tested before it.
148 #define TestImplAddr(Near) \
149 do { \
150 Label ForwardJmp; \
151 Label BackwardJmp; \
152 Label Done; \
153 \
154 __ jmp(&ForwardJmp, AssemblerX8632::k##Near##Jump); \
155 __ hlt(); \
156 __ hlt(); \
157 __ hlt(); \
158 __ hlt(); \
159 __ hlt(); \
160 __ hlt(); \
161 __ hlt(); \
162 __ hlt(); \
163 __ hlt(); \
164 __ hlt(); \
165 __ bind(&BackwardJmp); \
166 __ jmp(&Done, AssemblerX8632::k##Near##Jump); \
167 __ hlt(); \
168 __ hlt(); \
169 __ hlt(); \
170 __ hlt(); \
171 __ hlt(); \
172 __ hlt(); \
173 __ hlt(); \
174 __ hlt(); \
175 __ hlt(); \
176 __ hlt(); \
177 __ bind(&ForwardJmp); \
178 __ jmp(&BackwardJmp, AssemblerX8632::k##NearJump); \
179 __ hlt(); \
180 __ hlt(); \
181 __ hlt(); \
182 __ hlt(); \
183 __ hlt(); \
184 __ hlt(); \
185 __ hlt(); \
186 __ hlt(); \
187 __ hlt(); \
188 __ hlt(); \
189 __ bind(&Done); \
190 } while (0)
191
192 #define TestImplReg(Dst) \
193 do { \
194 __ call(Immediate(16)); \
195 Label Done; \
196 __ jmp(&Done, AssemblerX8632::kNearJump); \
197 __ hlt(); \
198 __ hlt(); \
199 __ hlt(); \
200 __ hlt(); \
201 __ hlt(); \
202 __ hlt(); \
203 __ hlt(); \
204 __ hlt(); \
205 __ hlt(); \
206 __ hlt(); \
207 __ popl(GPRRegister::Encoded_Reg_##Dst); \
208 __ jmp(GPRRegister::Encoded_Reg_##Dst); \
209 __ hlt(); \
210 __ hlt(); \
211 __ hlt(); \
212 __ hlt(); \
213 __ hlt(); \
214 __ hlt(); \
215 __ hlt(); \
216 __ hlt(); \
217 __ hlt(); \
218 __ hlt(); \
219 __ bind(&Done); \
220 \
221 AssembledTest test = assemble(); \
222 test.run(); \
223 \
224 reset(); \
225 } while (0)
226
227 TestImplAddr(Near);
228 TestImplAddr(Far);
229
230 TestImplReg(eax);
231 TestImplReg(ebx);
232 TestImplReg(ecx);
233 TestImplReg(edx);
234 TestImplReg(esi);
235 TestImplReg(edi);
236
237 #undef TestImplReg
238 #undef TestImplAddr
239 }
240
241 } // end of anonymous namespace
242 } // end of namespace Test
243 } // end of namespace X8632
244 } // end of namespace Ice
245