1 : // Copyright 2012 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 :
15 : #include "syzygy/core/assembler.h"
16 :
17 : #include <vector>
18 : #include "gtest/gtest.h"
19 :
20 : namespace core {
21 :
22 : namespace {
23 :
24 : class TestSerializer : public core::AssemblerImpl::InstructionSerializer {
25 : public:
26 : struct Reference {
27 : uint32 location;
28 : const void* ref;
29 : };
30 :
31 E : TestSerializer () {
32 E : }
33 :
34 : virtual void AppendInstruction(uint32 location,
35 : const uint8* bytes,
36 : size_t num_bytes,
37 : const uint32 *ref_locations,
38 : const void* const* refs,
39 E : size_t num_refs) {
40 E : for (size_t i = 0; i < num_refs; ++i) {
41 E : Reference ref = { code.size() + ref_locations[i], refs[i] };
42 E : references.push_back(ref);
43 E : }
44 E : code.insert(code.end(), bytes, bytes + num_bytes);
45 E : }
46 :
47 : std::vector<uint8> code;
48 : std::vector<Reference> references;
49 : };
50 :
51 : class AssemblerTest : public testing::Test {
52 : public:
53 E : AssemblerTest() : asm_(0, &serializer_) {
54 E : }
55 :
56 : TestSerializer serializer_;
57 : AssemblerImpl asm_;
58 : };
59 :
60 : #define EXPECT_BYTES(...) \
61 : do { \
62 : uint8 data[] = { __VA_ARGS__ }; \
63 : ASSERT_EQ(arraysize(data), serializer_.code.size()); \
64 : EXPECT_EQ(0, memcmp(data, &serializer_.code.at(0), arraysize(data))); \
65 : serializer_.code.clear(); \
66 : } while (0)
67 :
68 : } // namespace
69 :
70 E : TEST_F(AssemblerTest, Registers) {
71 E : EXPECT_EQ(kRegisterEax, eax.code());
72 E : EXPECT_EQ(kRegisterEcx, ecx.code());
73 E : EXPECT_EQ(kRegisterEdx, edx.code());
74 E : EXPECT_EQ(kRegisterEbx, ebx.code());
75 E : EXPECT_EQ(kRegisterEsp, esp.code());
76 E : EXPECT_EQ(kRegisterEbp, ebp.code());
77 E : EXPECT_EQ(kRegisterEsi, esi.code());
78 E : EXPECT_EQ(kRegisterEdi, edi.code());
79 E : }
80 :
81 E : TEST_F(AssemblerTest, ValueImpl) {
82 E : ValueImpl imm1;
83 E : EXPECT_EQ(0, imm1.value());
84 E : EXPECT_EQ(NULL, imm1.reference());
85 E : EXPECT_EQ(kSizeNone, imm1.size());
86 E : EXPECT_TRUE(imm1 == imm1);
87 :
88 E : ValueImpl imm2(0xCAFEBABE, kSize32Bit);
89 E : EXPECT_EQ(0xCAFEBABE, imm2.value());
90 E : EXPECT_EQ(NULL, imm2.reference());
91 E : EXPECT_EQ(kSize32Bit, imm2.size());
92 E : EXPECT_TRUE(imm2 == imm2);
93 E : EXPECT_FALSE(imm2 == imm1);
94 :
95 E : int ref2 = 0;
96 E : ValueImpl imm3(0xCAFEBABE, kSize32Bit, &ref2);
97 E : EXPECT_EQ(0xCAFEBABE, imm3.value());
98 E : EXPECT_EQ(&ref2, imm3.reference());
99 E : EXPECT_EQ(kSize32Bit, imm3.size());
100 E : EXPECT_TRUE(imm3 == imm3);
101 E : EXPECT_FALSE(imm3 == imm2);
102 E : EXPECT_FALSE(imm3 == imm1);
103 :
104 E : ValueImpl imm4(0xCAFEBABE, kSize32Bit, &ref2);
105 E : EXPECT_TRUE(imm4 == imm3);
106 E : }
107 :
108 E : TEST_F(AssemblerTest, OperandImpl) {
109 : {
110 E : OperandImpl op(edi);
111 E : EXPECT_EQ(kRegisterEdi, op.base());
112 E : EXPECT_EQ(kRegisterNone, op.index());
113 E : EXPECT_EQ(kTimes1, op.scale());
114 E : EXPECT_EQ(0, op.displacement().value());
115 E : EXPECT_EQ(NULL, op.displacement().reference());
116 E : EXPECT_EQ(kSizeNone, op.displacement().size());
117 : }
118 :
119 : {
120 E : int ref = 0;
121 E : OperandImpl op(ecx, DisplacementImpl(0xCAFEBABE, kSize32Bit, &ref));
122 E : EXPECT_EQ(kRegisterEcx, op.base());
123 E : EXPECT_EQ(kRegisterNone, op.index());
124 E : EXPECT_EQ(kTimes1, op.scale());
125 E : EXPECT_EQ(0xCAFEBABE, op.displacement().value());
126 E : EXPECT_EQ(&ref, op.displacement().reference());
127 E : EXPECT_EQ(kSize32Bit, op.displacement().size());
128 : }
129 :
130 : {
131 E : int ref = 0;
132 E : OperandImpl op(DisplacementImpl(0xCAFEBABE, kSize32Bit, &ref));
133 E : EXPECT_EQ(kRegisterNone, op.base());
134 E : EXPECT_EQ(kRegisterNone, op.index());
135 E : EXPECT_EQ(kTimes1, op.scale());
136 E : EXPECT_EQ(0xCAFEBABE, op.displacement().value());
137 E : EXPECT_EQ(&ref, op.displacement().reference());
138 E : EXPECT_EQ(kSize32Bit, op.displacement().size());
139 : }
140 :
141 : {
142 E : OperandImpl op(ebp, ecx, kTimes8);
143 E : EXPECT_EQ(kRegisterEbp, op.base());
144 E : EXPECT_EQ(kRegisterEcx, op.index());
145 E : EXPECT_EQ(kTimes8, op.scale());
146 E : EXPECT_EQ(0, op.displacement().value());
147 E : EXPECT_EQ(NULL, op.displacement().reference());
148 E : EXPECT_EQ(kSizeNone, op.displacement().size());
149 : }
150 :
151 : {
152 E : int ref = 0;
153 : OperandImpl
154 E : op(ebp, ecx, kTimes2, DisplacementImpl(0xCA, kSize8Bit, &ref));
155 E : EXPECT_EQ(kRegisterEbp, op.base());
156 E : EXPECT_EQ(kRegisterEcx, op.index());
157 E : EXPECT_EQ(kTimes2, op.scale());
158 E : EXPECT_EQ(0xCA, op.displacement().value());
159 E : EXPECT_EQ(&ref, op.displacement().reference());
160 E : EXPECT_EQ(kSize8Bit, op.displacement().size());
161 : }
162 E : }
163 :
164 E : TEST_F(AssemblerTest, Call) {
165 E : asm_.set_location(0xCAFEBABE);
166 :
167 : // Immediate call.
168 E : asm_.call(ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
169 E : EXPECT_BYTES(0xE8, 0xFB, 0xFF, 0xFF, 0xFF);
170 :
171 : // Indirect call - we test only one operand encoding, as the others
172 : // are well covered in the mov instruction.
173 E : asm_.call(OperandImpl(DisplacementImpl(0xCAFEBABE, kSize32Bit, NULL)));
174 E : EXPECT_BYTES(0xFF, 0x15, 0xBE, 0xBA, 0xFE, 0xCA);
175 E : }
176 :
177 E : TEST_F(AssemblerTest, Jmp) {
178 E : asm_.set_location(0xCAFEBABE);
179 :
180 : // Immediate 8-bit reach jmp.
181 E : asm_.jmp(ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
182 E : EXPECT_BYTES(0xEB, 0xFE);
183 :
184 E : ASSERT_EQ(1, AssemblerImpl::kShortJumpOpcodeSize);
185 E : ASSERT_EQ(2, AssemblerImpl::kShortJumpSize);
186 :
187 : // Immediate 32-bit reach jmp.
188 E : asm_.jmp(ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
189 E : EXPECT_BYTES(0xE9, 0xF9, 0xFF, 0xFF, 0xFF);
190 :
191 E : ASSERT_EQ(1, AssemblerImpl::kLongJumpOpcodeSize);
192 E : ASSERT_EQ(5, AssemblerImpl::kLongJumpSize);
193 :
194 : // Indirect jmp - we test only one operand encoding, as the others
195 : // are well covered in the mov instruction.
196 E : asm_.jmp(OperandImpl(DisplacementImpl(0xCAFEBABE, kSize32Bit, NULL)));
197 E : EXPECT_BYTES(0xFF, 0x25, 0xBE, 0xBA, 0xFE, 0xCA);
198 E : }
199 :
200 E : TEST_F(AssemblerTest, Ret) {
201 E : asm_.ret();
202 E : EXPECT_BYTES(0xC3);
203 :
204 E : asm_.ret(0x4);
205 E : EXPECT_BYTES(0xC2, 0x04, 0x00);
206 E : }
207 :
208 E : TEST_F(AssemblerTest, MovByte) {
209 : asm_.mov_b(OperandImpl(eax, ebx, kTimes4,
210 : DisplacementImpl(0xCAFEBABE, kSize32Bit)),
211 E : ImmediateImpl(0xCB, kSize8Bit));
212 E : EXPECT_BYTES(0xC6, 0x84, 0x98, 0xBE, 0xBA, 0xFE, 0xCA, 0xCB);
213 E : }
214 :
215 E : TEST_F(AssemblerTest, MovImmediate) {
216 : // Immediate moves.
217 E : asm_.mov(eax, ImmediateImpl(0xCAFEBABE, kSize32Bit));
218 E : EXPECT_BYTES(0xB8, 0xBE, 0xBA, 0xFE, 0xCA);
219 E : asm_.mov(ebx, ImmediateImpl(0xCAFEBABE, kSize32Bit));
220 E : EXPECT_BYTES(0xBB, 0xBE, 0xBA, 0xFE, 0xCA);
221 E : }
222 :
223 E : TEST_F(AssemblerTest, MovRegisterToRegister) {
224 : // Register to register, one case each for source and dst.
225 E : asm_.mov(eax, ebx);
226 E : EXPECT_BYTES(0x8B, 0xC3);
227 E : asm_.mov(ecx, eax);
228 E : EXPECT_BYTES(0x8B, 0xC8);
229 E : asm_.mov(ebx, eax);
230 E : EXPECT_BYTES(0x8B, 0xD8);
231 E : asm_.mov(edx, eax);
232 E : EXPECT_BYTES(0x8B, 0xD0);
233 E : asm_.mov(esp, eax);
234 E : EXPECT_BYTES(0x8B, 0xE0);
235 E : asm_.mov(ebp, eax);
236 E : EXPECT_BYTES(0x8B, 0xE8);
237 E : asm_.mov(esi, eax);
238 E : EXPECT_BYTES(0x8B, 0xF0);
239 E : asm_.mov(edi, eax);
240 E : EXPECT_BYTES(0x8B, 0xF8);
241 :
242 E : asm_.mov(ebx, eax);
243 E : EXPECT_BYTES(0x8B, 0xD8);
244 E : asm_.mov(eax, ecx);
245 E : EXPECT_BYTES(0x8B, 0xC1);
246 E : asm_.mov(eax, ebx);
247 E : EXPECT_BYTES(0x8B, 0xC3);
248 E : asm_.mov(eax, edx);
249 E : EXPECT_BYTES(0x8B, 0xC2);
250 E : asm_.mov(eax, esp);
251 E : EXPECT_BYTES(0x8B, 0xC4);
252 E : asm_.mov(eax, ebp);
253 E : EXPECT_BYTES(0x8B, 0xC5);
254 E : asm_.mov(eax, esi);
255 E : EXPECT_BYTES(0x8B, 0xC6);
256 E : asm_.mov(eax, edi);
257 E : EXPECT_BYTES(0x8B, 0xC7);
258 E : }
259 :
260 E : TEST_F(AssemblerTest, MovRegisterIndirect) {
261 : // Indirect register only source modes.
262 E : asm_.mov(ebx, OperandImpl(eax));
263 E : EXPECT_BYTES(0x8B, 0x18);
264 E : asm_.mov(eax, OperandImpl(ecx));
265 E : EXPECT_BYTES(0x8B, 0x01);
266 E : asm_.mov(edx, OperandImpl(ebx));
267 E : EXPECT_BYTES(0x8B, 0x13);
268 E : asm_.mov(ecx, OperandImpl(edx));
269 E : EXPECT_BYTES(0x8B, 0x0A);
270 :
271 : // Note that EBP is a special case that always requires a displacement.
272 E : asm_.mov(ebx, OperandImpl(ebp));
273 E : EXPECT_BYTES(0x8B, 0x5D, 0x00);
274 :
275 : // Note that ESP is a special case that always requires a SIB byte.
276 E : asm_.mov(ecx, OperandImpl(esp));
277 E : EXPECT_BYTES(0x8B, 0x0C, 0x24);
278 :
279 E : asm_.mov(ebx, OperandImpl(esi));
280 E : EXPECT_BYTES(0x8B, 0x1E);
281 E : asm_.mov(eax, OperandImpl(edi));
282 E : EXPECT_BYTES(0x8B, 0x07);
283 :
284 : // Indirect register destination modes.
285 E : asm_.mov(OperandImpl(eax), ebx);
286 E : EXPECT_BYTES(0x89, 0x18);
287 E : asm_.mov(OperandImpl(ecx), eax);
288 E : EXPECT_BYTES(0x89, 0x01);
289 E : asm_.mov(OperandImpl(ebx), edx);
290 E : EXPECT_BYTES(0x89, 0x13);
291 E : asm_.mov(OperandImpl(edx), ecx);
292 E : EXPECT_BYTES(0x89, 0x0A);
293 :
294 : // Note that EBP is a special case that always requires a displacement.
295 E : asm_.mov(OperandImpl(ebp), ebx);
296 E : EXPECT_BYTES(0x89, 0x5D, 0x00);
297 :
298 : // Note that ESP is a special case that always requires a SIB byte.
299 E : asm_.mov(OperandImpl(esp), ecx);
300 E : EXPECT_BYTES(0x89, 0x0C, 0x24);
301 :
302 E : asm_.mov(OperandImpl(esi), ebx);
303 E : EXPECT_BYTES(0x89, 0x1E);
304 E : asm_.mov(OperandImpl(edi), eax);
305 E : EXPECT_BYTES(0x89, 0x07);
306 E : }
307 :
308 E : TEST_F(AssemblerTest, MovRegisterDisplacementIndirect) {
309 : // Register & displacement source modes.
310 E : DisplacementImpl cafebabe(0xCAFEBABE, kSize32Bit, NULL);
311 :
312 E : asm_.mov(ebx, OperandImpl(eax, cafebabe));
313 E : EXPECT_BYTES(0x8B, 0x98, 0xBE, 0xBA, 0xFE, 0xCA);
314 E : asm_.mov(eax, OperandImpl(ecx, cafebabe));
315 E : EXPECT_BYTES(0x8B, 0x81, 0xBE, 0xBA, 0xFE, 0xCA);
316 E : asm_.mov(eax, OperandImpl(ebx, cafebabe));
317 E : EXPECT_BYTES(0x8B, 0x83, 0xBE, 0xBA, 0xFE, 0xCA);
318 E : asm_.mov(eax, OperandImpl(edx, cafebabe));
319 E : EXPECT_BYTES(0x8B, 0x82, 0xBE, 0xBA, 0xFE, 0xCA);
320 E : asm_.mov(eax, OperandImpl(ebp, cafebabe));
321 E : EXPECT_BYTES(0x8B, 0x85, 0xBE, 0xBA, 0xFE, 0xCA);
322 :
323 : // ESP requires a SIB byte and has a longer encoding.
324 E : asm_.mov(eax, OperandImpl(esp, cafebabe));
325 E : EXPECT_BYTES(0x8B, 0x84, 0x24, 0xBE, 0xBA, 0xFE, 0xCA);
326 :
327 E : asm_.mov(eax, OperandImpl(esi, cafebabe));
328 E : EXPECT_BYTES(0x8B, 0x86, 0xBE, 0xBA, 0xFE, 0xCA);
329 E : asm_.mov(eax, OperandImpl(edi, cafebabe));
330 E : EXPECT_BYTES(0x8B, 0x87, 0xBE, 0xBA, 0xFE, 0xCA);
331 :
332 : // And destination modes.
333 E : asm_.mov(OperandImpl(eax, cafebabe), ebx);
334 E : EXPECT_BYTES(0x89, 0x98, 0xBE, 0xBA, 0xFE, 0xCA);
335 E : asm_.mov(OperandImpl(ecx, cafebabe), eax);
336 E : EXPECT_BYTES(0x89, 0x81, 0xBE, 0xBA, 0xFE, 0xCA);
337 E : asm_.mov(OperandImpl(ebx, cafebabe), eax);
338 E : EXPECT_BYTES(0x89, 0x83, 0xBE, 0xBA, 0xFE, 0xCA);
339 E : asm_.mov(OperandImpl(edx, cafebabe), eax);
340 E : EXPECT_BYTES(0x89, 0x82, 0xBE, 0xBA, 0xFE, 0xCA);
341 E : asm_.mov(OperandImpl(ebp, cafebabe), eax);
342 E : EXPECT_BYTES(0x89, 0x85, 0xBE, 0xBA, 0xFE, 0xCA);
343 :
344 : // ESP requires a SIB byte and has a longer encoding.
345 E : asm_.mov(OperandImpl(esp, cafebabe), eax);
346 E : EXPECT_BYTES(0x89, 0x84, 0x24, 0xBE, 0xBA, 0xFE, 0xCA);
347 :
348 E : asm_.mov(OperandImpl(esi, cafebabe), eax);
349 E : EXPECT_BYTES(0x89, 0x86, 0xBE, 0xBA, 0xFE, 0xCA);
350 E : asm_.mov(OperandImpl(edi, cafebabe), eax);
351 E : EXPECT_BYTES(0x89, 0x87, 0xBE, 0xBA, 0xFE, 0xCA);
352 :
353 : // Test a sampling of 8-bit displacements.
354 E : DisplacementImpl ca(0xCA, kSize8Bit, NULL);
355 :
356 : // Source.
357 E : asm_.mov(ebx, OperandImpl(eax, ca));
358 E : EXPECT_BYTES(0x8B, 0x58, 0xCA);
359 :
360 : // ESP requires a SIB byte and has a longer encoding.
361 E : asm_.mov(eax, OperandImpl(esp, ca));
362 E : EXPECT_BYTES(0x8B, 0x44, 0x24, 0xCA);
363 :
364 : // And destination modes.
365 E : asm_.mov(OperandImpl(eax, ca), ebx);
366 E : EXPECT_BYTES(0x89, 0x58, 0xCA);
367 :
368 : // ESP requires a SIB byte and has a longer encoding.
369 E : asm_.mov(OperandImpl(esp, ca), eax);
370 E : EXPECT_BYTES(0x89, 0x44, 0x24, 0xCA);
371 E : }
372 :
373 E : TEST_F(AssemblerTest, MovDisplacementIndirect) {
374 : // Displacement-only mode.
375 E : DisplacementImpl cafebabe(0xCAFEBABE, kSize32Bit, NULL);
376 :
377 : // Source, note EAX has a shortcut encoding.
378 E : asm_.mov(eax, OperandImpl(cafebabe));
379 E : EXPECT_BYTES(0xA1, 0xBE, 0xBA, 0xFE, 0xCA);
380 E : asm_.mov(ecx, OperandImpl(cafebabe));
381 E : EXPECT_BYTES(0x8B, 0x0D, 0xBE, 0xBA, 0xFE, 0xCA);
382 :
383 : // Destination, again EAX is special.
384 E : asm_.mov(OperandImpl(cafebabe), eax);
385 E : EXPECT_BYTES(0xA3, 0xBE, 0xBA, 0xFE, 0xCA);
386 :
387 E : asm_.mov(OperandImpl(cafebabe), ecx);
388 E : EXPECT_BYTES(0x89, 0x0D, 0xBE, 0xBA, 0xFE, 0xCA);
389 E : }
390 :
391 E : TEST_F(AssemblerTest, MovRegisterBaseDisplacementScaleIndirect) {
392 : // There are 8 base * 7 index * 4 scales = 224 combinations.
393 : // We don't test all of them, but rather cycle through each of base,
394 : // index and scale individually.
395 E : DisplacementImpl cafebabe(0xCAFEBABE, kSize32Bit, NULL);
396 :
397 : // Source mode, base register.
398 E : asm_.mov(edx, OperandImpl(ecx, eax, kTimes4, cafebabe));
399 E : EXPECT_BYTES(0x8B, 0x94, 0x81, 0xBE, 0xBA, 0xFE, 0xCA);
400 E : asm_.mov(eax, OperandImpl(ecx, eax, kTimes4, cafebabe));
401 E : EXPECT_BYTES(0x8B, 0x84, 0x81, 0xBE, 0xBA, 0xFE, 0xCA);
402 E : asm_.mov(eax, OperandImpl(edx, eax, kTimes4, cafebabe));
403 E : EXPECT_BYTES(0x8B, 0x84, 0x82, 0xBE, 0xBA, 0xFE, 0xCA);
404 E : asm_.mov(eax, OperandImpl(ebx, eax, kTimes4, cafebabe));
405 E : EXPECT_BYTES(0x8B, 0x84, 0x83, 0xBE, 0xBA, 0xFE, 0xCA);
406 E : asm_.mov(eax, OperandImpl(esp, eax, kTimes4, cafebabe));
407 E : EXPECT_BYTES(0x8B, 0x84, 0x84, 0xBE, 0xBA, 0xFE, 0xCA);
408 E : asm_.mov(eax, OperandImpl(ebp, eax, kTimes4, cafebabe));
409 E : EXPECT_BYTES(0x8B, 0x84, 0x85, 0xBE, 0xBA, 0xFE, 0xCA);
410 E : asm_.mov(eax, OperandImpl(esi, eax, kTimes4, cafebabe));
411 E : EXPECT_BYTES(0x8B, 0x84, 0x86, 0xBE, 0xBA, 0xFE, 0xCA);
412 E : asm_.mov(eax, OperandImpl(edi, eax, kTimes4, cafebabe));
413 E : EXPECT_BYTES(0x8B, 0x84, 0x87, 0xBE, 0xBA, 0xFE, 0xCA);
414 :
415 : // Source mode, index register.
416 E : asm_.mov(ebx, OperandImpl(ecx, eax, kTimes4, cafebabe));
417 E : EXPECT_BYTES(0x8B, 0x9C, 0x81, 0xBE, 0xBA, 0xFE, 0xCA);
418 E : asm_.mov(eax, OperandImpl(eax, ecx, kTimes4, cafebabe));
419 E : EXPECT_BYTES(0x8B, 0x84, 0x88, 0xBE, 0xBA, 0xFE, 0xCA);
420 E : asm_.mov(eax, OperandImpl(eax, edx, kTimes4, cafebabe));
421 E : EXPECT_BYTES(0x8B, 0x84, 0x90, 0xBE, 0xBA, 0xFE, 0xCA);
422 E : asm_.mov(eax, OperandImpl(eax, ebx, kTimes4, cafebabe));
423 E : EXPECT_BYTES(0x8B, 0x84, 0x98, 0xBE, 0xBA, 0xFE, 0xCA);
424 E : asm_.mov(eax, OperandImpl(eax, ebp, kTimes4, cafebabe));
425 E : EXPECT_BYTES(0x8B, 0x84, 0xA8, 0xBE, 0xBA, 0xFE, 0xCA);
426 E : asm_.mov(eax, OperandImpl(eax, esi, kTimes4, cafebabe));
427 E : EXPECT_BYTES(0x8B, 0x84, 0xB0, 0xBE, 0xBA, 0xFE, 0xCA);
428 E : asm_.mov(eax, OperandImpl(eax, edi, kTimes4, cafebabe));
429 E : EXPECT_BYTES(0x8B, 0x84, 0xB8, 0xBE, 0xBA, 0xFE, 0xCA);
430 :
431 : // Source mode, Scale.
432 E : asm_.mov(ebx, OperandImpl(ecx, eax, kTimes1, cafebabe));
433 E : EXPECT_BYTES(0x8B, 0x9C, 0x01, 0xBE, 0xBA, 0xFE, 0xCA);
434 E : asm_.mov(ebx, OperandImpl(ecx, eax, kTimes2, cafebabe));
435 E : EXPECT_BYTES(0x8B, 0x9C, 0x41, 0xBE, 0xBA, 0xFE, 0xCA);
436 E : asm_.mov(ebx, OperandImpl(ecx, eax, kTimes4, cafebabe));
437 E : EXPECT_BYTES(0x8B, 0x9C, 0x81, 0xBE, 0xBA, 0xFE, 0xCA);
438 E : asm_.mov(ebx, OperandImpl(ecx, eax, kTimes8, cafebabe));
439 E : EXPECT_BYTES(0x8B, 0x9C, 0xC1, 0xBE, 0xBA, 0xFE, 0xCA);
440 :
441 : // Destination mode, base register.
442 E : asm_.mov(OperandImpl(eax, eax, kTimes4, cafebabe), ecx);
443 E : EXPECT_BYTES(0x89, 0x8C, 0x80, 0xBE, 0xBA, 0xFE, 0xCA);
444 E : asm_.mov(OperandImpl(ecx, eax, kTimes4, cafebabe), eax);
445 E : EXPECT_BYTES(0x89, 0x84, 0x81, 0xBE, 0xBA, 0xFE, 0xCA);
446 E : asm_.mov(OperandImpl(edx, eax, kTimes4, cafebabe), eax);
447 E : EXPECT_BYTES(0x89, 0x84, 0x82, 0xBE, 0xBA, 0xFE, 0xCA);
448 E : asm_.mov(OperandImpl(ebx, eax, kTimes4, cafebabe), eax);
449 E : EXPECT_BYTES(0x89, 0x84, 0x83, 0xBE, 0xBA, 0xFE, 0xCA);
450 E : asm_.mov(OperandImpl(esp, eax, kTimes4, cafebabe), eax);
451 E : EXPECT_BYTES(0x89, 0x84, 0x84, 0xBE, 0xBA, 0xFE, 0xCA);
452 E : asm_.mov(OperandImpl(ebp, eax, kTimes4, cafebabe), eax);
453 E : EXPECT_BYTES(0x89, 0x84, 0x85, 0xBE, 0xBA, 0xFE, 0xCA);
454 E : asm_.mov(OperandImpl(esi, eax, kTimes4, cafebabe), eax);
455 E : EXPECT_BYTES(0x89, 0x84, 0x86, 0xBE, 0xBA, 0xFE, 0xCA);
456 E : asm_.mov(OperandImpl(edi, eax, kTimes4, cafebabe), eax);
457 E : EXPECT_BYTES(0x89, 0x84, 0x87, 0xBE, 0xBA, 0xFE, 0xCA);
458 :
459 : // Destination mode, index register.
460 E : asm_.mov(OperandImpl(ecx, eax, kTimes4, cafebabe), ebx);
461 E : EXPECT_BYTES(0x89, 0x9C, 0x81, 0xBE, 0xBA, 0xFE, 0xCA);
462 E : asm_.mov(OperandImpl(eax, ecx, kTimes4, cafebabe), eax);
463 E : EXPECT_BYTES(0x89, 0x84, 0x88, 0xBE, 0xBA, 0xFE, 0xCA);
464 E : asm_.mov(OperandImpl(eax, edx, kTimes4, cafebabe), eax);
465 E : EXPECT_BYTES(0x89, 0x84, 0x90, 0xBE, 0xBA, 0xFE, 0xCA);
466 E : asm_.mov(OperandImpl(eax, ebx, kTimes4, cafebabe), eax);
467 E : EXPECT_BYTES(0x89, 0x84, 0x98, 0xBE, 0xBA, 0xFE, 0xCA);
468 E : asm_.mov(OperandImpl(eax, ebp, kTimes4, cafebabe), eax);
469 E : EXPECT_BYTES(0x89, 0x84, 0xA8, 0xBE, 0xBA, 0xFE, 0xCA);
470 E : asm_.mov(OperandImpl(eax, esi, kTimes4, cafebabe), eax);
471 E : EXPECT_BYTES(0x89, 0x84, 0xB0, 0xBE, 0xBA, 0xFE, 0xCA);
472 E : asm_.mov(OperandImpl(eax, edi, kTimes4, cafebabe), eax);
473 E : EXPECT_BYTES(0x89, 0x84, 0xB8, 0xBE, 0xBA, 0xFE, 0xCA);
474 :
475 : // Destination mode, Scale.
476 E : asm_.mov(OperandImpl(ecx, eax, kTimes1, cafebabe), ebx);
477 E : EXPECT_BYTES(0x89, 0x9C, 0x01, 0xBE, 0xBA, 0xFE, 0xCA);
478 E : asm_.mov(OperandImpl(ecx, eax, kTimes2, cafebabe), ebx);
479 E : EXPECT_BYTES(0x89, 0x9C, 0x41, 0xBE, 0xBA, 0xFE, 0xCA);
480 E : asm_.mov(OperandImpl(ecx, eax, kTimes4, cafebabe), ebx);
481 E : EXPECT_BYTES(0x89, 0x9C, 0x81, 0xBE, 0xBA, 0xFE, 0xCA);
482 E : asm_.mov(OperandImpl(ecx, eax, kTimes8, cafebabe), ebx);
483 E : EXPECT_BYTES(0x89, 0x9C, 0xC1, 0xBE, 0xBA, 0xFE, 0xCA);
484 E : }
485 :
486 E : TEST_F(AssemblerTest, MovRegisterBaseIndexScaleIndirect) {
487 : // Tests the displacement-less [base + index * scale].
488 E : asm_.mov(edx, OperandImpl(esi, eax, kTimes8));
489 E : EXPECT_BYTES(0x8B, 0x14, 0xC6);
490 E : }
491 :
492 E : TEST_F(AssemblerTest, MovRegisterDisplacementScaleIndirect) {
493 : // Tests [index * scale + displ] modes, which are always encoded with a
494 : // 32-bit displacement, including [index * scale], which has a zero 32-bit
495 : // displacement that will be omitted from disassembly.
496 :
497 E : DisplacementImpl one(1, kSize8Bit, NULL);
498 :
499 : // Source mode.
500 E : asm_.mov(edx, OperandImpl(eax, kTimes4, one));
501 E : EXPECT_BYTES(0x8B, 0x14, 0x85, 0x01, 0x00, 0x00, 0x00);
502 E : asm_.mov(edx, OperandImpl(ecx, kTimes4, one));
503 E : EXPECT_BYTES(0x8B, 0x14, 0x8D, 0x01, 0x00, 0x00, 0x00);
504 E : asm_.mov(edx, OperandImpl(edx, kTimes4, one));
505 E : EXPECT_BYTES(0x8B, 0x14, 0x95, 0x01, 0x00, 0x00, 0x00);
506 E : asm_.mov(edx, OperandImpl(ebx, kTimes4, one));
507 E : EXPECT_BYTES(0x8B, 0x14, 0x9D, 0x01, 0x00, 0x00, 0x00);
508 E : asm_.mov(edx, OperandImpl(ebp, kTimes4, one));
509 E : EXPECT_BYTES(0x8B, 0x14, 0xAD, 0x01, 0x00, 0x00, 0x00);
510 E : asm_.mov(edx, OperandImpl(esi, kTimes4, one));
511 E : EXPECT_BYTES(0x8B, 0x14, 0xB5, 0x01, 0x00, 0x00, 0x00);
512 E : asm_.mov(edx, OperandImpl(edi, kTimes4, one));
513 E : EXPECT_BYTES(0x8B, 0x14, 0xBD, 0x01, 0x00, 0x00, 0x00);
514 :
515 : // Destination mode.
516 E : asm_.mov(OperandImpl(eax, kTimes4, one), edx);
517 E : EXPECT_BYTES(0x89, 0x14, 0x85, 0x01, 0x00, 0x00, 0x00);
518 E : asm_.mov(OperandImpl(ecx, kTimes4, one), edx);
519 E : EXPECT_BYTES(0x89, 0x14, 0x8D, 0x01, 0x00, 0x00, 0x00);
520 E : asm_.mov(OperandImpl(edx, kTimes4, one), edx);
521 E : EXPECT_BYTES(0x89, 0x14, 0x95, 0x01, 0x00, 0x00, 0x00);
522 E : asm_.mov(OperandImpl(ebx, kTimes4, one), edx);
523 E : EXPECT_BYTES(0x89, 0x14, 0x9D, 0x01, 0x00, 0x00, 0x00);
524 E : asm_.mov(OperandImpl(ebp, kTimes4, one), edx);
525 E : EXPECT_BYTES(0x89, 0x14, 0xAD, 0x01, 0x00, 0x00, 0x00);
526 E : asm_.mov(OperandImpl(esi, kTimes4, one), edx);
527 E : EXPECT_BYTES(0x89, 0x14, 0xB5, 0x01, 0x00, 0x00, 0x00);
528 E : asm_.mov(OperandImpl(edi, kTimes4, one), edx);
529 E : EXPECT_BYTES(0x89, 0x14, 0xBD, 0x01, 0x00, 0x00, 0x00);
530 E : }
531 :
532 E : TEST_F(AssemblerTest, MovImmToRegisterDisplacementScaleIndirect) {
533 E : DisplacementImpl cafebabe(0xCAFEBABE, kSize32Bit, NULL);
534 E : ImmediateImpl deadbeef(0xDEADBEEF, kSize32Bit, NULL);
535 :
536 : // We expect the operand encoding has been adequately tested elsewhere,
537 : // so we only test one variant here.
538 E : asm_.mov(OperandImpl(ecx, eax, kTimes4, cafebabe), deadbeef);
539 : EXPECT_BYTES(0xC7, 0x84, 0x81,
540 : 0xBE, 0xBA, 0xFE, 0xCA,
541 E : 0xEF, 0xBE, 0xAD, 0xDE);
542 E : }
543 :
544 E : TEST_F(AssemblerTest, LeaRegisterIndirect) {
545 : // Indirect register only source modes.
546 E : asm_.lea(ebx, OperandImpl(eax));
547 E : EXPECT_BYTES(0x8D, 0x18);
548 E : asm_.lea(eax, OperandImpl(ecx));
549 E : EXPECT_BYTES(0x8D, 0x01);
550 E : asm_.lea(edx, OperandImpl(ebx));
551 E : EXPECT_BYTES(0x8D, 0x13);
552 E : asm_.lea(ecx, OperandImpl(edx));
553 E : EXPECT_BYTES(0x8D, 0x0A);
554 :
555 : // Note that EBP is a special case that always requires a displacement.
556 E : asm_.lea(ebx, OperandImpl(ebp));
557 E : EXPECT_BYTES(0x8D, 0x5D, 0x00);
558 :
559 : // Note that ESP is a special case that always requires a SIB byte.
560 E : asm_.lea(ecx, OperandImpl(esp));
561 E : EXPECT_BYTES(0x8D, 0x0C, 0x24);
562 :
563 E : asm_.lea(ebx, OperandImpl(esi));
564 E : EXPECT_BYTES(0x8D, 0x1E);
565 E : asm_.lea(eax, OperandImpl(edi));
566 E : EXPECT_BYTES(0x8D, 0x07);
567 E : }
568 :
569 E : TEST_F(AssemblerTest, LeaRegisterDisplacementIndirect) {
570 : // Register & displacement source modes.
571 E : DisplacementImpl cafebabe(0xCAFEBABE, kSize32Bit, NULL);
572 :
573 E : asm_.lea(ebx, OperandImpl(eax, cafebabe));
574 E : EXPECT_BYTES(0x8D, 0x98, 0xBE, 0xBA, 0xFE, 0xCA);
575 E : asm_.lea(eax, OperandImpl(ecx, cafebabe));
576 E : EXPECT_BYTES(0x8D, 0x81, 0xBE, 0xBA, 0xFE, 0xCA);
577 E : asm_.lea(eax, OperandImpl(ebx, cafebabe));
578 E : EXPECT_BYTES(0x8D, 0x83, 0xBE, 0xBA, 0xFE, 0xCA);
579 E : asm_.lea(eax, OperandImpl(edx, cafebabe));
580 E : EXPECT_BYTES(0x8D, 0x82, 0xBE, 0xBA, 0xFE, 0xCA);
581 E : asm_.lea(eax, OperandImpl(ebp, cafebabe));
582 E : EXPECT_BYTES(0x8D, 0x85, 0xBE, 0xBA, 0xFE, 0xCA);
583 :
584 : // ESP requires a SIB byte and has a longer encoding.
585 E : asm_.lea(eax, OperandImpl(esp, cafebabe));
586 E : EXPECT_BYTES(0x8D, 0x84, 0x24, 0xBE, 0xBA, 0xFE, 0xCA);
587 :
588 E : asm_.lea(eax, OperandImpl(esi, cafebabe));
589 E : EXPECT_BYTES(0x8D, 0x86, 0xBE, 0xBA, 0xFE, 0xCA);
590 E : asm_.lea(eax, OperandImpl(edi, cafebabe));
591 E : EXPECT_BYTES(0x8D, 0x87, 0xBE, 0xBA, 0xFE, 0xCA);
592 :
593 : // Test a sampling of 8-bit displacements.
594 E : DisplacementImpl ca(0xCA, kSize8Bit, NULL);
595 :
596 : // Source.
597 E : asm_.lea(ebx, OperandImpl(eax, ca));
598 E : EXPECT_BYTES(0x8D, 0x58, 0xCA);
599 :
600 : // ESP requires a SIB byte and has a longer encoding.
601 E : asm_.lea(eax, OperandImpl(esp, ca));
602 E : EXPECT_BYTES(0x8D, 0x44, 0x24, 0xCA);
603 E : }
604 :
605 E : TEST_F(AssemblerTest, LeaDisplacementIndirect) {
606 : // Displacement-only mode.
607 E : DisplacementImpl cafebabe(0xCAFEBABE, kSize32Bit, NULL);
608 :
609 E : asm_.lea(eax, OperandImpl(cafebabe));
610 E : EXPECT_BYTES(0x8D, 0x05, 0xBE, 0xBA, 0xFE, 0xCA);
611 E : asm_.lea(ecx, OperandImpl(cafebabe));
612 E : EXPECT_BYTES(0x8D, 0x0D, 0xBE, 0xBA, 0xFE, 0xCA);
613 E : }
614 :
615 E : TEST_F(AssemblerTest, LeaRegisterDisplacementScaleIndirect) {
616 : // There are 8 base * 7 index * 4 scales = 224 combinations.
617 : // We don't test all of them, but rather cycle through each of base,
618 : // index and scale individually.
619 E : DisplacementImpl cafebabe(0xCAFEBABE, kSize32Bit, NULL);
620 :
621 : // Source mode, base register.
622 E : asm_.lea(edx, OperandImpl(ecx, eax, kTimes4, cafebabe));
623 E : EXPECT_BYTES(0x8D, 0x94, 0x81, 0xBE, 0xBA, 0xFE, 0xCA);
624 E : asm_.lea(eax, OperandImpl(ecx, eax, kTimes4, cafebabe));
625 E : EXPECT_BYTES(0x8D, 0x84, 0x81, 0xBE, 0xBA, 0xFE, 0xCA);
626 E : asm_.lea(eax, OperandImpl(edx, eax, kTimes4, cafebabe));
627 E : EXPECT_BYTES(0x8D, 0x84, 0x82, 0xBE, 0xBA, 0xFE, 0xCA);
628 E : asm_.lea(eax, OperandImpl(ebx, eax, kTimes4, cafebabe));
629 E : EXPECT_BYTES(0x8D, 0x84, 0x83, 0xBE, 0xBA, 0xFE, 0xCA);
630 E : asm_.lea(eax, OperandImpl(esp, eax, kTimes4, cafebabe));
631 E : EXPECT_BYTES(0x8D, 0x84, 0x84, 0xBE, 0xBA, 0xFE, 0xCA);
632 E : asm_.lea(eax, OperandImpl(ebp, eax, kTimes4, cafebabe));
633 E : EXPECT_BYTES(0x8D, 0x84, 0x85, 0xBE, 0xBA, 0xFE, 0xCA);
634 E : asm_.lea(eax, OperandImpl(esi, eax, kTimes4, cafebabe));
635 E : EXPECT_BYTES(0x8D, 0x84, 0x86, 0xBE, 0xBA, 0xFE, 0xCA);
636 E : asm_.lea(eax, OperandImpl(edi, eax, kTimes4, cafebabe));
637 E : EXPECT_BYTES(0x8D, 0x84, 0x87, 0xBE, 0xBA, 0xFE, 0xCA);
638 :
639 : // Source mode, index register.
640 E : asm_.lea(ebx, OperandImpl(ecx, eax, kTimes4, cafebabe));
641 E : EXPECT_BYTES(0x8D, 0x9C, 0x81, 0xBE, 0xBA, 0xFE, 0xCA);
642 E : asm_.lea(eax, OperandImpl(eax, ecx, kTimes4, cafebabe));
643 E : EXPECT_BYTES(0x8D, 0x84, 0x88, 0xBE, 0xBA, 0xFE, 0xCA);
644 E : asm_.lea(eax, OperandImpl(eax, edx, kTimes4, cafebabe));
645 E : EXPECT_BYTES(0x8D, 0x84, 0x90, 0xBE, 0xBA, 0xFE, 0xCA);
646 E : asm_.lea(eax, OperandImpl(eax, ebx, kTimes4, cafebabe));
647 E : EXPECT_BYTES(0x8D, 0x84, 0x98, 0xBE, 0xBA, 0xFE, 0xCA);
648 E : asm_.lea(eax, OperandImpl(eax, ebp, kTimes4, cafebabe));
649 E : EXPECT_BYTES(0x8D, 0x84, 0xA8, 0xBE, 0xBA, 0xFE, 0xCA);
650 E : asm_.lea(eax, OperandImpl(eax, esi, kTimes4, cafebabe));
651 E : EXPECT_BYTES(0x8D, 0x84, 0xB0, 0xBE, 0xBA, 0xFE, 0xCA);
652 E : asm_.lea(eax, OperandImpl(eax, edi, kTimes4, cafebabe));
653 E : EXPECT_BYTES(0x8D, 0x84, 0xB8, 0xBE, 0xBA, 0xFE, 0xCA);
654 :
655 : // Source mode, Scale.
656 E : asm_.lea(ebx, OperandImpl(ecx, eax, kTimes1, cafebabe));
657 E : EXPECT_BYTES(0x8D, 0x9C, 0x01, 0xBE, 0xBA, 0xFE, 0xCA);
658 E : asm_.lea(ebx, OperandImpl(ecx, eax, kTimes2, cafebabe));
659 E : EXPECT_BYTES(0x8D, 0x9C, 0x41, 0xBE, 0xBA, 0xFE, 0xCA);
660 E : asm_.lea(ebx, OperandImpl(ecx, eax, kTimes4, cafebabe));
661 E : EXPECT_BYTES(0x8D, 0x9C, 0x81, 0xBE, 0xBA, 0xFE, 0xCA);
662 E : asm_.lea(ebx, OperandImpl(ecx, eax, kTimes8, cafebabe));
663 E : EXPECT_BYTES(0x8D, 0x9C, 0xC1, 0xBE, 0xBA, 0xFE, 0xCA);
664 E : }
665 :
666 E : TEST_F(AssemblerTest, Push) {
667 : // Register push.
668 E : asm_.push(eax);
669 E : asm_.push(ecx);
670 E : asm_.push(edx);
671 E : asm_.push(ebx);
672 E : asm_.push(esp);
673 E : asm_.push(ebp);
674 E : asm_.push(esi);
675 E : asm_.push(edi);
676 E : EXPECT_BYTES(0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57);
677 :
678 : // Immediate push.
679 E : asm_.push(ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
680 E : EXPECT_BYTES(0x68, 0xBE, 0xBA, 0xFE, 0xCA);
681 :
682 : // General push, try one variant as the rest are OperandImpl encodings.
683 E : asm_.push(OperandImpl(DisplacementImpl(0xCAFEBABE, kSize32Bit, NULL)));
684 E : EXPECT_BYTES(0xFF, 0x35, 0xBE, 0xBA, 0xFE, 0xCA);
685 E : }
686 :
687 E : TEST_F(AssemblerTest, Pop) {
688 : // Register pop.
689 E : asm_.pop(eax);
690 E : asm_.pop(ecx);
691 E : asm_.pop(edx);
692 E : asm_.pop(ebx);
693 E : asm_.pop(esp);
694 E : asm_.pop(ebp);
695 E : asm_.pop(esi);
696 E : asm_.pop(edi);
697 E : EXPECT_BYTES(0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F);
698 :
699 : // General pop, try one variant as the rest are OperandImpl encodings.
700 E : asm_.pop(OperandImpl(DisplacementImpl(0xCAFEBABE, kSize32Bit, NULL)));
701 E : EXPECT_BYTES(0x8F, 0x05, 0xBE, 0xBA, 0xFE, 0xCA);
702 E : }
703 :
704 E : TEST_F(AssemblerTest, Ja) {
705 E : ConditionCode cc = kAbove;
706 E : asm_.set_location(0xCAFEBABE);
707 :
708 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
709 E : EXPECT_BYTES(0x77, 0xFE);
710 :
711 E : ASSERT_EQ(1, AssemblerImpl::kShortBranchOpcodeSize);
712 E : ASSERT_EQ(2, AssemblerImpl::kShortBranchSize);
713 :
714 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
715 E : EXPECT_BYTES(0x0F, 0x87, 0xF8, 0xFF, 0xFF, 0xFF);
716 :
717 E : ASSERT_EQ(2, AssemblerImpl::kLongBranchOpcodeSize);
718 E : ASSERT_EQ(6, AssemblerImpl::kLongBranchSize);
719 E : }
720 :
721 E : TEST_F(AssemblerTest, Jae) {
722 E : ConditionCode cc = kAboveEqual;
723 E : asm_.set_location(0xCAFEBABE);
724 :
725 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
726 E : EXPECT_BYTES(0x73, 0xFE);
727 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
728 E : EXPECT_BYTES(0x0F, 0x83, 0xF8, 0xFF, 0xFF, 0xFF);
729 E : }
730 :
731 E : TEST_F(AssemblerTest, Jb) {
732 E : ConditionCode cc = kBelow;
733 E : asm_.set_location(0xCAFEBABE);
734 :
735 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
736 E : EXPECT_BYTES(0x72, 0xFE);
737 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
738 E : EXPECT_BYTES(0x0F, 0x82, 0xF8, 0xFF, 0xFF, 0xFF);
739 E : }
740 :
741 E : TEST_F(AssemblerTest, Jbe) {
742 E : ConditionCode cc = kBelowEqual;
743 E : asm_.set_location(0xCAFEBABE);
744 :
745 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
746 E : EXPECT_BYTES(0x76, 0xFE);
747 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
748 E : EXPECT_BYTES(0x0F, 0x86, 0xF8, 0xFF, 0xFF, 0xFF);
749 E : }
750 :
751 E : TEST_F(AssemblerTest, Jc) {
752 E : ConditionCode cc = kCarry;
753 E : asm_.set_location(0xCAFEBABE);
754 :
755 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
756 E : EXPECT_BYTES(0x72, 0xFE);
757 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
758 E : EXPECT_BYTES(0x0F, 0x82, 0xF8, 0xFF, 0xFF, 0xFF);
759 E : }
760 :
761 E : TEST_F(AssemblerTest, Je) {
762 E : ConditionCode cc = kEqual;
763 E : asm_.set_location(0xCAFEBABE);
764 :
765 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
766 E : EXPECT_BYTES(0x74, 0xFE);
767 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
768 E : EXPECT_BYTES(0x0F, 0x84, 0xF8, 0xFF, 0xFF, 0xFF);
769 E : }
770 :
771 E : TEST_F(AssemblerTest, Jecxz) {
772 E : asm_.set_location(0xCAFEBABE);
773 :
774 E : asm_.jecxz(ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
775 E : EXPECT_BYTES(0xE3, 0xFE);
776 E : }
777 :
778 E : TEST_F(AssemblerTest, Jg) {
779 E : ConditionCode cc = kGreater;
780 E : asm_.set_location(0xCAFEBABE);
781 :
782 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
783 E : EXPECT_BYTES(0x7F, 0xFE);
784 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
785 E : EXPECT_BYTES(0x0F, 0x8F, 0xF8, 0xFF, 0xFF, 0xFF);
786 E : }
787 :
788 E : TEST_F(AssemblerTest, Jge) {
789 E : ConditionCode cc = kGreaterEqual;
790 E : asm_.set_location(0xCAFEBABE);
791 :
792 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
793 E : EXPECT_BYTES(0x7D, 0xFE);
794 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
795 E : EXPECT_BYTES(0x0F, 0x8D, 0xF8, 0xFF, 0xFF, 0xFF);
796 E : }
797 :
798 E : TEST_F(AssemblerTest, Jl) {
799 E : ConditionCode cc = kLess;
800 E : asm_.set_location(0xCAFEBABE);
801 :
802 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
803 E : EXPECT_BYTES(0x7C, 0xFE);
804 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
805 E : EXPECT_BYTES(0x0F, 0x8C, 0xF8, 0xFF, 0xFF, 0xFF);
806 E : }
807 :
808 E : TEST_F(AssemblerTest, Jle) {
809 E : ConditionCode cc = kLessEqual;
810 E : asm_.set_location(0xCAFEBABE);
811 :
812 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
813 E : EXPECT_BYTES(0x7E, 0xFE);
814 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
815 E : EXPECT_BYTES(0x0F, 0x8E, 0xF8, 0xFF, 0xFF, 0xFF);
816 E : }
817 :
818 E : TEST_F(AssemblerTest, Jo) {
819 E : ConditionCode cc = kOverflow;
820 E : asm_.set_location(0xCAFEBABE);
821 :
822 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
823 E : EXPECT_BYTES(0x70, 0xFE);
824 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
825 E : EXPECT_BYTES(0x0F, 0x80, 0xF8, 0xFF, 0xFF, 0xFF);
826 E : }
827 :
828 E : TEST_F(AssemblerTest, Jpe) {
829 E : ConditionCode cc = kParityEven;
830 E : asm_.set_location(0xCAFEBABE);
831 :
832 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
833 E : EXPECT_BYTES(0x7A, 0xFE);
834 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
835 E : EXPECT_BYTES(0x0F, 0x8A, 0xF8, 0xFF, 0xFF, 0xFF);
836 E : }
837 :
838 E : TEST_F(AssemblerTest, Jpo) {
839 E : ConditionCode cc = kParityOdd;
840 E : asm_.set_location(0xCAFEBABE);
841 :
842 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
843 E : EXPECT_BYTES(0x7B, 0xFE);
844 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
845 E : EXPECT_BYTES(0x0F, 0x8B, 0xF8, 0xFF, 0xFF, 0xFF);
846 E : }
847 :
848 E : TEST_F(AssemblerTest, Js) {
849 E : ConditionCode cc = kSign;
850 E : asm_.set_location(0xCAFEBABE);
851 : COMPILE_ASSERT(kSign == kNegative, kSignAndPositiveAreAliases);
852 :
853 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
854 E : EXPECT_BYTES(0x78, 0xFE);
855 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
856 E : EXPECT_BYTES(0x0F, 0x88, 0xF8, 0xFF, 0xFF, 0xFF);
857 E : }
858 :
859 E : TEST_F(AssemblerTest, Jz) {
860 E : ConditionCode cc = kZero;
861 E : asm_.set_location(0xCAFEBABE);
862 :
863 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
864 E : EXPECT_BYTES(0x74, 0xFE);
865 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
866 E : EXPECT_BYTES(0x0F, 0x84, 0xF8, 0xFF, 0xFF, 0xFF);
867 E : }
868 :
869 E : TEST_F(AssemblerTest, Jnc) {
870 E : ConditionCode cc = kNotCarry;
871 E : asm_.set_location(0xCAFEBABE);
872 :
873 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
874 E : EXPECT_BYTES(0x73, 0xFE);
875 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
876 E : EXPECT_BYTES(0x0F, 0x83, 0xF8, 0xFF, 0xFF, 0xFF);
877 E : }
878 :
879 E : TEST_F(AssemblerTest, Jne) {
880 E : ConditionCode cc = kNotEqual;
881 E : asm_.set_location(0xCAFEBABE);
882 :
883 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
884 E : EXPECT_BYTES(0x75, 0xFE);
885 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
886 E : EXPECT_BYTES(0x0F, 0x85, 0xF8, 0xFF, 0xFF, 0xFF);
887 E : }
888 :
889 E : TEST_F(AssemblerTest, Jno) {
890 E : ConditionCode cc = kNoOverflow;
891 E : asm_.set_location(0xCAFEBABE);
892 :
893 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
894 E : EXPECT_BYTES(0x71, 0xFE);
895 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
896 E : EXPECT_BYTES(0x0F, 0x81, 0xF8, 0xFF, 0xFF, 0xFF);
897 E : }
898 :
899 E : TEST_F(AssemblerTest, Jns) {
900 : COMPILE_ASSERT(kNotSign == kPositive, kSignAndPositiveAreAliases);
901 E : ConditionCode cc = kNotSign;
902 E : asm_.set_location(0xCAFEBABE);
903 :
904 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
905 E : EXPECT_BYTES(0x79, 0xFE);
906 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
907 E : EXPECT_BYTES(0x0F, 0x89, 0xF8, 0xFF, 0xFF, 0xFF);
908 E : }
909 :
910 E : TEST_F(AssemblerTest, Jnz) {
911 E : ConditionCode cc = kNotZero;
912 E : asm_.set_location(0xCAFEBABE);
913 :
914 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
915 E : EXPECT_BYTES(0x75, 0xFE);
916 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
917 E : EXPECT_BYTES(0x0F, 0x85, 0xF8, 0xFF, 0xFF, 0xFF);
918 E : }
919 :
920 E : TEST_F(AssemblerTest, Loop) {
921 E : asm_.set_location(0xCAFEBABE);
922 :
923 E : asm_.loop(ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
924 E : EXPECT_BYTES(0xE2, 0xFE);
925 E : }
926 :
927 E : TEST_F(AssemblerTest, Loope) {
928 E : asm_.set_location(0xCAFEBABE);
929 :
930 E : asm_.loope(ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
931 E : EXPECT_BYTES(0xE1, 0xFE);
932 E : }
933 :
934 E : TEST_F(AssemblerTest, Loopne) {
935 E : asm_.set_location(0xCAFEBABE);
936 :
937 E : asm_.loopne(ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
938 E : EXPECT_BYTES(0xE0, 0xFE);
939 E : }
940 :
941 E : TEST_F(AssemblerTest, References) {
942 : // We arbitrarily use the MOV instruction to test reference propagation.
943 : static const int ref1 = 1;
944 E : asm_.mov(eax, ImmediateImpl(0, kSize8Bit, &ref1));
945 :
946 : static const int ref2 = 2;
947 : asm_.mov(eax, OperandImpl(eax, ebx, kTimes4,
948 E : DisplacementImpl(0, kSize32Bit, &ref2)));
949 :
950 : static const int ref3 = 3;
951 : static const int ref4 = 4;
952 : asm_.mov(OperandImpl(eax, ebx, kTimes4,
953 : DisplacementImpl(0, kSize32Bit, &ref3)),
954 E : ImmediateImpl(0, kSize32Bit, &ref4));
955 :
956 E : EXPECT_EQ(4, serializer_.references.size());
957 :
958 E : EXPECT_EQ(1, serializer_.references[0].location);
959 E : EXPECT_EQ(&ref1, serializer_.references[0].ref);
960 :
961 E : EXPECT_EQ(8, serializer_.references[1].location);
962 E : EXPECT_EQ(&ref2, serializer_.references[1].ref);
963 :
964 E : EXPECT_EQ(15, serializer_.references[2].location);
965 E : EXPECT_EQ(&ref3, serializer_.references[2].ref);
966 :
967 E : EXPECT_EQ(19, serializer_.references[3].location);
968 E : EXPECT_EQ(&ref4, serializer_.references[3].ref);
969 E : }
970 :
971 : } // namespace core
|