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