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 : #include "syzygy/core/disassembler_util.h"
20 :
21 : namespace core {
22 :
23 : namespace {
24 :
25 : class TestSerializer : public core::AssemblerImpl::InstructionSerializer {
26 : public:
27 : struct Reference {
28 : uint32 location;
29 : const void* ref;
30 : };
31 :
32 E : TestSerializer() {
33 E : }
34 :
35 : virtual void AppendInstruction(uint32 location,
36 : const uint8* bytes,
37 : size_t num_bytes,
38 : const uint32 *ref_locations,
39 : const void* const* refs,
40 E : size_t num_refs) {
41 E : for (size_t i = 0; i < num_refs; ++i) {
42 E : Reference ref = { code.size() + ref_locations[i], refs[i] };
43 E : references.push_back(ref);
44 E : }
45 E : code.insert(code.end(), bytes, bytes + num_bytes);
46 E : }
47 :
48 : std::vector<uint8> code;
49 : std::vector<Reference> references;
50 : };
51 :
52 : class AssemblerTest : public testing::Test {
53 : public:
54 E : AssemblerTest() : asm_(0, &serializer_) {
55 E : }
56 :
57 : TestSerializer serializer_;
58 : AssemblerImpl asm_;
59 : };
60 :
61 : #define EXPECT_BYTES(...) \
62 : do { \
63 : uint8 data[] = { __VA_ARGS__ }; \
64 : ASSERT_EQ(arraysize(data), serializer_.code.size()); \
65 : EXPECT_EQ(0, memcmp(data, &serializer_.code.at(0), arraysize(data))); \
66 : serializer_.code.clear(); \
67 : } while (0)
68 :
69 : } // namespace
70 :
71 E : TEST_F(AssemblerTest, ValueImpl) {
72 E : ValueImpl imm1;
73 E : EXPECT_EQ(0, imm1.value());
74 E : EXPECT_EQ(NULL, imm1.reference());
75 E : EXPECT_EQ(kSizeNone, imm1.size());
76 E : EXPECT_TRUE(imm1 == imm1);
77 :
78 E : ValueImpl imm2(0xCAFEBABE, kSize32Bit);
79 E : EXPECT_EQ(0xCAFEBABE, imm2.value());
80 E : EXPECT_EQ(NULL, imm2.reference());
81 E : EXPECT_EQ(kSize32Bit, imm2.size());
82 E : EXPECT_TRUE(imm2 == imm2);
83 E : EXPECT_FALSE(imm2 == imm1);
84 :
85 E : int ref2 = 0;
86 E : ValueImpl imm3(0xCAFEBABE, kSize32Bit, &ref2);
87 E : EXPECT_EQ(0xCAFEBABE, imm3.value());
88 E : EXPECT_EQ(&ref2, imm3.reference());
89 E : EXPECT_EQ(kSize32Bit, imm3.size());
90 E : EXPECT_TRUE(imm3 == imm3);
91 E : EXPECT_FALSE(imm3 == imm2);
92 E : EXPECT_FALSE(imm3 == imm1);
93 :
94 E : ValueImpl imm4(0xCAFEBABE, kSize32Bit, &ref2);
95 E : EXPECT_TRUE(imm4 == imm3);
96 E : }
97 :
98 E : TEST_F(AssemblerTest, OperandImpl) {
99 : {
100 E : OperandImpl op(edi);
101 E : EXPECT_EQ(kRegisterEdi, op.base());
102 E : EXPECT_EQ(kRegisterNone, op.index());
103 E : EXPECT_EQ(kTimes1, op.scale());
104 E : EXPECT_EQ(0, op.displacement().value());
105 E : EXPECT_EQ(NULL, op.displacement().reference());
106 E : EXPECT_EQ(kSizeNone, op.displacement().size());
107 : }
108 :
109 : {
110 E : int ref = 0;
111 E : OperandImpl op(ecx, DisplacementImpl(0xCAFEBABE, kSize32Bit, &ref));
112 E : EXPECT_EQ(kRegisterEcx, op.base());
113 E : EXPECT_EQ(kRegisterNone, op.index());
114 E : EXPECT_EQ(kTimes1, op.scale());
115 E : EXPECT_EQ(0xCAFEBABE, op.displacement().value());
116 E : EXPECT_EQ(&ref, op.displacement().reference());
117 E : EXPECT_EQ(kSize32Bit, op.displacement().size());
118 : }
119 :
120 : {
121 E : int ref = 0;
122 E : OperandImpl op(DisplacementImpl(0xCAFEBABE, kSize32Bit, &ref));
123 E : EXPECT_EQ(kRegisterNone, op.base());
124 E : EXPECT_EQ(kRegisterNone, op.index());
125 E : EXPECT_EQ(kTimes1, op.scale());
126 E : EXPECT_EQ(0xCAFEBABE, op.displacement().value());
127 E : EXPECT_EQ(&ref, op.displacement().reference());
128 E : EXPECT_EQ(kSize32Bit, op.displacement().size());
129 : }
130 :
131 : {
132 E : OperandImpl op(ebp, ecx, kTimes8);
133 E : EXPECT_EQ(kRegisterEbp, op.base());
134 E : EXPECT_EQ(kRegisterEcx, op.index());
135 E : EXPECT_EQ(kTimes8, op.scale());
136 E : EXPECT_EQ(0, op.displacement().value());
137 E : EXPECT_EQ(NULL, op.displacement().reference());
138 E : EXPECT_EQ(kSizeNone, op.displacement().size());
139 : }
140 :
141 : {
142 E : int ref = 0;
143 : OperandImpl
144 E : op(ebp, ecx, kTimes2, DisplacementImpl(0xCA, kSize8Bit, &ref));
145 E : EXPECT_EQ(kRegisterEbp, op.base());
146 E : EXPECT_EQ(kRegisterEcx, op.index());
147 E : EXPECT_EQ(kTimes2, op.scale());
148 E : EXPECT_EQ(0xCA, op.displacement().value());
149 E : EXPECT_EQ(&ref, op.displacement().reference());
150 E : EXPECT_EQ(kSize8Bit, op.displacement().size());
151 : }
152 E : }
153 :
154 E : TEST_F(AssemblerTest, Nop) {
155 E : asm_.nop(0);
156 E : EXPECT_TRUE(serializer_.code.empty());
157 :
158 : // NOPs are generated in bunches of instructions of up to 15 bytes in
159 : // length. We validate that each one of them is in fact a sequence of NOPs.
160 E : for (size_t i = 1; i <= 15; ++i) {
161 E : asm_.nop(i);
162 E : EXPECT_EQ(i, serializer_.code.size());
163 :
164 : // The sequence of bytes should consist of NOP instructions.
165 E : size_t j = 0;
166 E : size_t instruction_count = 0;
167 E : while (j < i) {
168 E : _DInst instruction = {};
169 : ASSERT_TRUE(DecodeOneInstruction(serializer_.code.data() + j,
170 : i - j,
171 E : &instruction));
172 E : ASSERT_TRUE(IsNop(instruction));
173 E : j += instruction.size;
174 E : ++instruction_count;
175 E : }
176 : // 1 or 2 instructions should be generated.
177 E : ASSERT_LT(0u, instruction_count);
178 E : ASSERT_GE(2u, instruction_count);
179 E : serializer_.code.clear();
180 E : }
181 E : }
182 :
183 E : TEST_F(AssemblerTest, Call) {
184 E : asm_.set_location(0xCAFEBABE);
185 :
186 : // Immediate call.
187 E : asm_.call(ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
188 E : EXPECT_BYTES(0xE8, 0xFB, 0xFF, 0xFF, 0xFF);
189 :
190 : // Indirect call - we test only one operand encoding, as the others
191 : // are well covered in the mov instruction.
192 E : asm_.call(OperandImpl(DisplacementImpl(0xCAFEBABE, kSize32Bit, NULL)));
193 E : EXPECT_BYTES(0xFF, 0x15, 0xBE, 0xBA, 0xFE, 0xCA);
194 E : }
195 :
196 E : TEST_F(AssemblerTest, Jmp) {
197 E : asm_.set_location(0xCAFEBABE);
198 :
199 : // Immediate 8-bit reach jmp.
200 E : asm_.jmp(ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
201 E : EXPECT_BYTES(0xEB, 0xFE);
202 :
203 E : ASSERT_EQ(1, AssemblerImpl::kShortJumpOpcodeSize);
204 E : ASSERT_EQ(2, AssemblerImpl::kShortJumpSize);
205 :
206 : // Immediate 32-bit reach jmp.
207 E : asm_.jmp(ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
208 E : EXPECT_BYTES(0xE9, 0xF9, 0xFF, 0xFF, 0xFF);
209 :
210 E : ASSERT_EQ(1, AssemblerImpl::kLongJumpOpcodeSize);
211 E : ASSERT_EQ(5, AssemblerImpl::kLongJumpSize);
212 :
213 : // Indirect jmp - we test only one operand encoding, as the others
214 : // are well covered in the mov instruction.
215 E : asm_.jmp(OperandImpl(DisplacementImpl(0xCAFEBABE, kSize32Bit, NULL)));
216 E : EXPECT_BYTES(0xFF, 0x25, 0xBE, 0xBA, 0xFE, 0xCA);
217 E : }
218 :
219 E : TEST_F(AssemblerTest, Ret) {
220 E : asm_.ret();
221 E : EXPECT_BYTES(0xC3);
222 :
223 E : asm_.ret(0x4);
224 E : EXPECT_BYTES(0xC2, 0x04, 0x00);
225 E : }
226 :
227 E : TEST_F(AssemblerTest, MovByte) {
228 : asm_.mov_b(OperandImpl(eax, ebx, kTimes4,
229 : DisplacementImpl(0xCAFEBABE, kSize32Bit)),
230 E : ImmediateImpl(0xCB, kSize8Bit));
231 E : EXPECT_BYTES(0xC6, 0x84, 0x98, 0xBE, 0xBA, 0xFE, 0xCA, 0xCB);
232 E : }
233 :
234 E : TEST_F(AssemblerTest, MovzxByte) {
235 E : asm_.movzx_b(eax, OperandImpl(ebx));
236 E : EXPECT_BYTES(0x0F, 0xB6, 0x03);
237 :
238 E : asm_.movzx_b(ecx, OperandImpl(ecx, edx, kTimes2));
239 E : EXPECT_BYTES(0x0F, 0xB6, 0x0C, 0x51);
240 E : }
241 :
242 E : TEST_F(AssemblerTest, MovImmediate) {
243 : // Immediate moves.
244 E : asm_.mov(eax, ImmediateImpl(0xCAFEBABE, kSize32Bit));
245 E : EXPECT_BYTES(0xB8, 0xBE, 0xBA, 0xFE, 0xCA);
246 E : asm_.mov(ebx, ImmediateImpl(0xCAFEBABE, kSize32Bit));
247 E : EXPECT_BYTES(0xBB, 0xBE, 0xBA, 0xFE, 0xCA);
248 E : }
249 :
250 E : TEST_F(AssemblerTest, MovRegisterToRegister) {
251 : // Register to register, one case each for source and dst.
252 E : asm_.mov(eax, ebx);
253 E : EXPECT_BYTES(0x8B, 0xC3);
254 E : asm_.mov(ecx, eax);
255 E : EXPECT_BYTES(0x8B, 0xC8);
256 E : asm_.mov(ebx, eax);
257 E : EXPECT_BYTES(0x8B, 0xD8);
258 E : asm_.mov(edx, eax);
259 E : EXPECT_BYTES(0x8B, 0xD0);
260 E : asm_.mov(esp, eax);
261 E : EXPECT_BYTES(0x8B, 0xE0);
262 E : asm_.mov(ebp, eax);
263 E : EXPECT_BYTES(0x8B, 0xE8);
264 E : asm_.mov(esi, eax);
265 E : EXPECT_BYTES(0x8B, 0xF0);
266 E : asm_.mov(edi, eax);
267 E : EXPECT_BYTES(0x8B, 0xF8);
268 :
269 E : asm_.mov(ebx, eax);
270 E : EXPECT_BYTES(0x8B, 0xD8);
271 E : asm_.mov(eax, ecx);
272 E : EXPECT_BYTES(0x8B, 0xC1);
273 E : asm_.mov(eax, ebx);
274 E : EXPECT_BYTES(0x8B, 0xC3);
275 E : asm_.mov(eax, edx);
276 E : EXPECT_BYTES(0x8B, 0xC2);
277 E : asm_.mov(eax, esp);
278 E : EXPECT_BYTES(0x8B, 0xC4);
279 E : asm_.mov(eax, ebp);
280 E : EXPECT_BYTES(0x8B, 0xC5);
281 E : asm_.mov(eax, esi);
282 E : EXPECT_BYTES(0x8B, 0xC6);
283 E : asm_.mov(eax, edi);
284 E : EXPECT_BYTES(0x8B, 0xC7);
285 E : }
286 :
287 E : TEST_F(AssemblerTest, MovRegisterIndirect) {
288 : // Indirect register only source modes.
289 E : asm_.mov(ebx, OperandImpl(eax));
290 E : EXPECT_BYTES(0x8B, 0x18);
291 E : asm_.mov(eax, OperandImpl(ecx));
292 E : EXPECT_BYTES(0x8B, 0x01);
293 E : asm_.mov(edx, OperandImpl(ebx));
294 E : EXPECT_BYTES(0x8B, 0x13);
295 E : asm_.mov(ecx, OperandImpl(edx));
296 E : EXPECT_BYTES(0x8B, 0x0A);
297 :
298 : // Note that EBP is a special case that always requires a displacement.
299 E : asm_.mov(ebx, OperandImpl(ebp));
300 E : EXPECT_BYTES(0x8B, 0x5D, 0x00);
301 :
302 : // Note that ESP is a special case that always requires a SIB byte.
303 E : asm_.mov(ecx, OperandImpl(esp));
304 E : EXPECT_BYTES(0x8B, 0x0C, 0x24);
305 :
306 E : asm_.mov(ebx, OperandImpl(esi));
307 E : EXPECT_BYTES(0x8B, 0x1E);
308 E : asm_.mov(eax, OperandImpl(edi));
309 E : EXPECT_BYTES(0x8B, 0x07);
310 :
311 : // Indirect register destination modes.
312 E : asm_.mov(OperandImpl(eax), ebx);
313 E : EXPECT_BYTES(0x89, 0x18);
314 E : asm_.mov(OperandImpl(ecx), eax);
315 E : EXPECT_BYTES(0x89, 0x01);
316 E : asm_.mov(OperandImpl(ebx), edx);
317 E : EXPECT_BYTES(0x89, 0x13);
318 E : asm_.mov(OperandImpl(edx), ecx);
319 E : EXPECT_BYTES(0x89, 0x0A);
320 :
321 : // Note that EBP is a special case that always requires a displacement.
322 E : asm_.mov(OperandImpl(ebp), ebx);
323 E : EXPECT_BYTES(0x89, 0x5D, 0x00);
324 :
325 : // Note that ESP is a special case that always requires a SIB byte.
326 E : asm_.mov(OperandImpl(esp), ecx);
327 E : EXPECT_BYTES(0x89, 0x0C, 0x24);
328 :
329 E : asm_.mov(OperandImpl(esi), ebx);
330 E : EXPECT_BYTES(0x89, 0x1E);
331 E : asm_.mov(OperandImpl(edi), eax);
332 E : EXPECT_BYTES(0x89, 0x07);
333 E : }
334 :
335 E : TEST_F(AssemblerTest, MovRegisterDisplacementIndirect) {
336 : // Register & displacement source modes.
337 E : DisplacementImpl cafebabe(0xCAFEBABE, kSize32Bit, NULL);
338 :
339 E : asm_.mov(ebx, OperandImpl(eax, cafebabe));
340 E : EXPECT_BYTES(0x8B, 0x98, 0xBE, 0xBA, 0xFE, 0xCA);
341 E : asm_.mov(eax, OperandImpl(ecx, cafebabe));
342 E : EXPECT_BYTES(0x8B, 0x81, 0xBE, 0xBA, 0xFE, 0xCA);
343 E : asm_.mov(eax, OperandImpl(ebx, cafebabe));
344 E : EXPECT_BYTES(0x8B, 0x83, 0xBE, 0xBA, 0xFE, 0xCA);
345 E : asm_.mov(eax, OperandImpl(edx, cafebabe));
346 E : EXPECT_BYTES(0x8B, 0x82, 0xBE, 0xBA, 0xFE, 0xCA);
347 E : asm_.mov(eax, OperandImpl(ebp, cafebabe));
348 E : EXPECT_BYTES(0x8B, 0x85, 0xBE, 0xBA, 0xFE, 0xCA);
349 :
350 : // ESP requires a SIB byte and has a longer encoding.
351 E : asm_.mov(eax, OperandImpl(esp, cafebabe));
352 E : EXPECT_BYTES(0x8B, 0x84, 0x24, 0xBE, 0xBA, 0xFE, 0xCA);
353 :
354 E : asm_.mov(eax, OperandImpl(esi, cafebabe));
355 E : EXPECT_BYTES(0x8B, 0x86, 0xBE, 0xBA, 0xFE, 0xCA);
356 E : asm_.mov(eax, OperandImpl(edi, cafebabe));
357 E : EXPECT_BYTES(0x8B, 0x87, 0xBE, 0xBA, 0xFE, 0xCA);
358 :
359 : // And destination modes.
360 E : asm_.mov(OperandImpl(eax, cafebabe), ebx);
361 E : EXPECT_BYTES(0x89, 0x98, 0xBE, 0xBA, 0xFE, 0xCA);
362 E : asm_.mov(OperandImpl(ecx, cafebabe), eax);
363 E : EXPECT_BYTES(0x89, 0x81, 0xBE, 0xBA, 0xFE, 0xCA);
364 E : asm_.mov(OperandImpl(ebx, cafebabe), eax);
365 E : EXPECT_BYTES(0x89, 0x83, 0xBE, 0xBA, 0xFE, 0xCA);
366 E : asm_.mov(OperandImpl(edx, cafebabe), eax);
367 E : EXPECT_BYTES(0x89, 0x82, 0xBE, 0xBA, 0xFE, 0xCA);
368 E : asm_.mov(OperandImpl(ebp, cafebabe), eax);
369 E : EXPECT_BYTES(0x89, 0x85, 0xBE, 0xBA, 0xFE, 0xCA);
370 :
371 : // ESP requires a SIB byte and has a longer encoding.
372 E : asm_.mov(OperandImpl(esp, cafebabe), eax);
373 E : EXPECT_BYTES(0x89, 0x84, 0x24, 0xBE, 0xBA, 0xFE, 0xCA);
374 :
375 E : asm_.mov(OperandImpl(esi, cafebabe), eax);
376 E : EXPECT_BYTES(0x89, 0x86, 0xBE, 0xBA, 0xFE, 0xCA);
377 E : asm_.mov(OperandImpl(edi, cafebabe), eax);
378 E : EXPECT_BYTES(0x89, 0x87, 0xBE, 0xBA, 0xFE, 0xCA);
379 :
380 : // Test a sampling of 8-bit displacements.
381 E : DisplacementImpl ca(0xCA, kSize8Bit, NULL);
382 :
383 : // Source.
384 E : asm_.mov(ebx, OperandImpl(eax, ca));
385 E : EXPECT_BYTES(0x8B, 0x58, 0xCA);
386 :
387 : // ESP requires a SIB byte and has a longer encoding.
388 E : asm_.mov(eax, OperandImpl(esp, ca));
389 E : EXPECT_BYTES(0x8B, 0x44, 0x24, 0xCA);
390 :
391 : // And destination modes.
392 E : asm_.mov(OperandImpl(eax, ca), ebx);
393 E : EXPECT_BYTES(0x89, 0x58, 0xCA);
394 :
395 : // ESP requires a SIB byte and has a longer encoding.
396 E : asm_.mov(OperandImpl(esp, ca), eax);
397 E : EXPECT_BYTES(0x89, 0x44, 0x24, 0xCA);
398 E : }
399 :
400 E : TEST_F(AssemblerTest, MovDisplacementIndirect) {
401 : // Displacement-only mode.
402 E : DisplacementImpl cafebabe(0xCAFEBABE, kSize32Bit, NULL);
403 :
404 : // Source, note EAX has a shortcut encoding.
405 E : asm_.mov(eax, OperandImpl(cafebabe));
406 E : EXPECT_BYTES(0xA1, 0xBE, 0xBA, 0xFE, 0xCA);
407 E : asm_.mov(ecx, OperandImpl(cafebabe));
408 E : EXPECT_BYTES(0x8B, 0x0D, 0xBE, 0xBA, 0xFE, 0xCA);
409 :
410 : // Destination, again EAX is special.
411 E : asm_.mov(OperandImpl(cafebabe), eax);
412 E : EXPECT_BYTES(0xA3, 0xBE, 0xBA, 0xFE, 0xCA);
413 :
414 E : asm_.mov(OperandImpl(cafebabe), ecx);
415 E : EXPECT_BYTES(0x89, 0x0D, 0xBE, 0xBA, 0xFE, 0xCA);
416 E : }
417 :
418 E : TEST_F(AssemblerTest, MovRegisterBaseDisplacementScaleIndirect) {
419 : // There are 8 base * 7 index * 4 scales = 224 combinations.
420 : // We don't test all of them, but rather cycle through each of base,
421 : // index and scale individually.
422 E : DisplacementImpl cafebabe(0xCAFEBABE, kSize32Bit, NULL);
423 :
424 : // Source mode, base register.
425 E : asm_.mov(edx, OperandImpl(ecx, eax, kTimes4, cafebabe));
426 E : EXPECT_BYTES(0x8B, 0x94, 0x81, 0xBE, 0xBA, 0xFE, 0xCA);
427 E : asm_.mov(eax, OperandImpl(ecx, eax, kTimes4, cafebabe));
428 E : EXPECT_BYTES(0x8B, 0x84, 0x81, 0xBE, 0xBA, 0xFE, 0xCA);
429 E : asm_.mov(eax, OperandImpl(edx, eax, kTimes4, cafebabe));
430 E : EXPECT_BYTES(0x8B, 0x84, 0x82, 0xBE, 0xBA, 0xFE, 0xCA);
431 E : asm_.mov(eax, OperandImpl(ebx, eax, kTimes4, cafebabe));
432 E : EXPECT_BYTES(0x8B, 0x84, 0x83, 0xBE, 0xBA, 0xFE, 0xCA);
433 E : asm_.mov(eax, OperandImpl(esp, eax, kTimes4, cafebabe));
434 E : EXPECT_BYTES(0x8B, 0x84, 0x84, 0xBE, 0xBA, 0xFE, 0xCA);
435 E : asm_.mov(eax, OperandImpl(ebp, eax, kTimes4, cafebabe));
436 E : EXPECT_BYTES(0x8B, 0x84, 0x85, 0xBE, 0xBA, 0xFE, 0xCA);
437 E : asm_.mov(eax, OperandImpl(esi, eax, kTimes4, cafebabe));
438 E : EXPECT_BYTES(0x8B, 0x84, 0x86, 0xBE, 0xBA, 0xFE, 0xCA);
439 E : asm_.mov(eax, OperandImpl(edi, eax, kTimes4, cafebabe));
440 E : EXPECT_BYTES(0x8B, 0x84, 0x87, 0xBE, 0xBA, 0xFE, 0xCA);
441 :
442 : // Source mode, index register.
443 E : asm_.mov(ebx, OperandImpl(ecx, eax, kTimes4, cafebabe));
444 E : EXPECT_BYTES(0x8B, 0x9C, 0x81, 0xBE, 0xBA, 0xFE, 0xCA);
445 E : asm_.mov(eax, OperandImpl(eax, ecx, kTimes4, cafebabe));
446 E : EXPECT_BYTES(0x8B, 0x84, 0x88, 0xBE, 0xBA, 0xFE, 0xCA);
447 E : asm_.mov(eax, OperandImpl(eax, edx, kTimes4, cafebabe));
448 E : EXPECT_BYTES(0x8B, 0x84, 0x90, 0xBE, 0xBA, 0xFE, 0xCA);
449 E : asm_.mov(eax, OperandImpl(eax, ebx, kTimes4, cafebabe));
450 E : EXPECT_BYTES(0x8B, 0x84, 0x98, 0xBE, 0xBA, 0xFE, 0xCA);
451 E : asm_.mov(eax, OperandImpl(eax, ebp, kTimes4, cafebabe));
452 E : EXPECT_BYTES(0x8B, 0x84, 0xA8, 0xBE, 0xBA, 0xFE, 0xCA);
453 E : asm_.mov(eax, OperandImpl(eax, esi, kTimes4, cafebabe));
454 E : EXPECT_BYTES(0x8B, 0x84, 0xB0, 0xBE, 0xBA, 0xFE, 0xCA);
455 E : asm_.mov(eax, OperandImpl(eax, edi, kTimes4, cafebabe));
456 E : EXPECT_BYTES(0x8B, 0x84, 0xB8, 0xBE, 0xBA, 0xFE, 0xCA);
457 :
458 : // Source mode, Scale.
459 E : asm_.mov(ebx, OperandImpl(ecx, eax, kTimes1, cafebabe));
460 E : EXPECT_BYTES(0x8B, 0x9C, 0x01, 0xBE, 0xBA, 0xFE, 0xCA);
461 E : asm_.mov(ebx, OperandImpl(ecx, eax, kTimes2, cafebabe));
462 E : EXPECT_BYTES(0x8B, 0x9C, 0x41, 0xBE, 0xBA, 0xFE, 0xCA);
463 E : asm_.mov(ebx, OperandImpl(ecx, eax, kTimes4, cafebabe));
464 E : EXPECT_BYTES(0x8B, 0x9C, 0x81, 0xBE, 0xBA, 0xFE, 0xCA);
465 E : asm_.mov(ebx, OperandImpl(ecx, eax, kTimes8, cafebabe));
466 E : EXPECT_BYTES(0x8B, 0x9C, 0xC1, 0xBE, 0xBA, 0xFE, 0xCA);
467 :
468 : // Destination mode, base register.
469 E : asm_.mov(OperandImpl(eax, eax, kTimes4, cafebabe), ecx);
470 E : EXPECT_BYTES(0x89, 0x8C, 0x80, 0xBE, 0xBA, 0xFE, 0xCA);
471 E : asm_.mov(OperandImpl(ecx, eax, kTimes4, cafebabe), eax);
472 E : EXPECT_BYTES(0x89, 0x84, 0x81, 0xBE, 0xBA, 0xFE, 0xCA);
473 E : asm_.mov(OperandImpl(edx, eax, kTimes4, cafebabe), eax);
474 E : EXPECT_BYTES(0x89, 0x84, 0x82, 0xBE, 0xBA, 0xFE, 0xCA);
475 E : asm_.mov(OperandImpl(ebx, eax, kTimes4, cafebabe), eax);
476 E : EXPECT_BYTES(0x89, 0x84, 0x83, 0xBE, 0xBA, 0xFE, 0xCA);
477 E : asm_.mov(OperandImpl(esp, eax, kTimes4, cafebabe), eax);
478 E : EXPECT_BYTES(0x89, 0x84, 0x84, 0xBE, 0xBA, 0xFE, 0xCA);
479 E : asm_.mov(OperandImpl(ebp, eax, kTimes4, cafebabe), eax);
480 E : EXPECT_BYTES(0x89, 0x84, 0x85, 0xBE, 0xBA, 0xFE, 0xCA);
481 E : asm_.mov(OperandImpl(esi, eax, kTimes4, cafebabe), eax);
482 E : EXPECT_BYTES(0x89, 0x84, 0x86, 0xBE, 0xBA, 0xFE, 0xCA);
483 E : asm_.mov(OperandImpl(edi, eax, kTimes4, cafebabe), eax);
484 E : EXPECT_BYTES(0x89, 0x84, 0x87, 0xBE, 0xBA, 0xFE, 0xCA);
485 :
486 : // Destination mode, index register.
487 E : asm_.mov(OperandImpl(ecx, eax, kTimes4, cafebabe), ebx);
488 E : EXPECT_BYTES(0x89, 0x9C, 0x81, 0xBE, 0xBA, 0xFE, 0xCA);
489 E : asm_.mov(OperandImpl(eax, ecx, kTimes4, cafebabe), eax);
490 E : EXPECT_BYTES(0x89, 0x84, 0x88, 0xBE, 0xBA, 0xFE, 0xCA);
491 E : asm_.mov(OperandImpl(eax, edx, kTimes4, cafebabe), eax);
492 E : EXPECT_BYTES(0x89, 0x84, 0x90, 0xBE, 0xBA, 0xFE, 0xCA);
493 E : asm_.mov(OperandImpl(eax, ebx, kTimes4, cafebabe), eax);
494 E : EXPECT_BYTES(0x89, 0x84, 0x98, 0xBE, 0xBA, 0xFE, 0xCA);
495 E : asm_.mov(OperandImpl(eax, ebp, kTimes4, cafebabe), eax);
496 E : EXPECT_BYTES(0x89, 0x84, 0xA8, 0xBE, 0xBA, 0xFE, 0xCA);
497 E : asm_.mov(OperandImpl(eax, esi, kTimes4, cafebabe), eax);
498 E : EXPECT_BYTES(0x89, 0x84, 0xB0, 0xBE, 0xBA, 0xFE, 0xCA);
499 E : asm_.mov(OperandImpl(eax, edi, kTimes4, cafebabe), eax);
500 E : EXPECT_BYTES(0x89, 0x84, 0xB8, 0xBE, 0xBA, 0xFE, 0xCA);
501 :
502 : // Destination mode, Scale.
503 E : asm_.mov(OperandImpl(ecx, eax, kTimes1, cafebabe), ebx);
504 E : EXPECT_BYTES(0x89, 0x9C, 0x01, 0xBE, 0xBA, 0xFE, 0xCA);
505 E : asm_.mov(OperandImpl(ecx, eax, kTimes2, cafebabe), ebx);
506 E : EXPECT_BYTES(0x89, 0x9C, 0x41, 0xBE, 0xBA, 0xFE, 0xCA);
507 E : asm_.mov(OperandImpl(ecx, eax, kTimes4, cafebabe), ebx);
508 E : EXPECT_BYTES(0x89, 0x9C, 0x81, 0xBE, 0xBA, 0xFE, 0xCA);
509 E : asm_.mov(OperandImpl(ecx, eax, kTimes8, cafebabe), ebx);
510 E : EXPECT_BYTES(0x89, 0x9C, 0xC1, 0xBE, 0xBA, 0xFE, 0xCA);
511 E : }
512 :
513 E : TEST_F(AssemblerTest, MovRegisterBaseIndexScaleIndirect) {
514 : // Tests the displacement-less [base + index * scale].
515 E : asm_.mov(edx, OperandImpl(esi, eax, kTimes8));
516 E : EXPECT_BYTES(0x8B, 0x14, 0xC6);
517 E : }
518 :
519 E : TEST_F(AssemblerTest, MovRegisterDisplacementScaleIndirect) {
520 : // Tests [index * scale + displ] modes, which are always encoded with a
521 : // 32-bit displacement, including [index * scale], which has a zero 32-bit
522 : // displacement that will be omitted from disassembly.
523 :
524 E : DisplacementImpl one(1, kSize8Bit, NULL);
525 :
526 : // Source mode.
527 E : asm_.mov(edx, OperandImpl(eax, kTimes4, one));
528 E : EXPECT_BYTES(0x8B, 0x14, 0x85, 0x01, 0x00, 0x00, 0x00);
529 E : asm_.mov(edx, OperandImpl(ecx, kTimes4, one));
530 E : EXPECT_BYTES(0x8B, 0x14, 0x8D, 0x01, 0x00, 0x00, 0x00);
531 E : asm_.mov(edx, OperandImpl(edx, kTimes4, one));
532 E : EXPECT_BYTES(0x8B, 0x14, 0x95, 0x01, 0x00, 0x00, 0x00);
533 E : asm_.mov(edx, OperandImpl(ebx, kTimes4, one));
534 E : EXPECT_BYTES(0x8B, 0x14, 0x9D, 0x01, 0x00, 0x00, 0x00);
535 E : asm_.mov(edx, OperandImpl(ebp, kTimes4, one));
536 E : EXPECT_BYTES(0x8B, 0x14, 0xAD, 0x01, 0x00, 0x00, 0x00);
537 E : asm_.mov(edx, OperandImpl(esi, kTimes4, one));
538 E : EXPECT_BYTES(0x8B, 0x14, 0xB5, 0x01, 0x00, 0x00, 0x00);
539 E : asm_.mov(edx, OperandImpl(edi, kTimes4, one));
540 E : EXPECT_BYTES(0x8B, 0x14, 0xBD, 0x01, 0x00, 0x00, 0x00);
541 :
542 : // Destination mode.
543 E : asm_.mov(OperandImpl(eax, kTimes4, one), edx);
544 E : EXPECT_BYTES(0x89, 0x14, 0x85, 0x01, 0x00, 0x00, 0x00);
545 E : asm_.mov(OperandImpl(ecx, kTimes4, one), edx);
546 E : EXPECT_BYTES(0x89, 0x14, 0x8D, 0x01, 0x00, 0x00, 0x00);
547 E : asm_.mov(OperandImpl(edx, kTimes4, one), edx);
548 E : EXPECT_BYTES(0x89, 0x14, 0x95, 0x01, 0x00, 0x00, 0x00);
549 E : asm_.mov(OperandImpl(ebx, kTimes4, one), edx);
550 E : EXPECT_BYTES(0x89, 0x14, 0x9D, 0x01, 0x00, 0x00, 0x00);
551 E : asm_.mov(OperandImpl(ebp, kTimes4, one), edx);
552 E : EXPECT_BYTES(0x89, 0x14, 0xAD, 0x01, 0x00, 0x00, 0x00);
553 E : asm_.mov(OperandImpl(esi, kTimes4, one), edx);
554 E : EXPECT_BYTES(0x89, 0x14, 0xB5, 0x01, 0x00, 0x00, 0x00);
555 E : asm_.mov(OperandImpl(edi, kTimes4, one), edx);
556 E : EXPECT_BYTES(0x89, 0x14, 0xBD, 0x01, 0x00, 0x00, 0x00);
557 E : }
558 :
559 E : TEST_F(AssemblerTest, MovImmToRegisterDisplacementScaleIndirect) {
560 E : DisplacementImpl cafebabe(0xCAFEBABE, kSize32Bit, NULL);
561 E : ImmediateImpl deadbeef(0xDEADBEEF, kSize32Bit, NULL);
562 :
563 : // We expect the operand encoding has been adequately tested elsewhere,
564 : // so we only test one variant here.
565 E : asm_.mov(OperandImpl(ecx, eax, kTimes4, cafebabe), deadbeef);
566 : EXPECT_BYTES(0xC7, 0x84, 0x81,
567 : 0xBE, 0xBA, 0xFE, 0xCA,
568 E : 0xEF, 0xBE, 0xAD, 0xDE);
569 E : }
570 :
571 E : TEST_F(AssemblerTest, MovWithSegmentPrefix) {
572 : // Indirect register destination modes.
573 E : asm_.mov_fs(OperandImpl(eax), ebx);
574 E : EXPECT_BYTES(0x64, 0x89, 0x18);
575 E : asm_.mov_fs(OperandImpl(ecx), eax);
576 E : EXPECT_BYTES(0x64, 0x89, 0x01);
577 E : asm_.mov_fs(OperandImpl(ebx), edx);
578 E : EXPECT_BYTES(0x64, 0x89, 0x13);
579 E : asm_.mov_fs(OperandImpl(edx), ecx);
580 E : EXPECT_BYTES(0x64, 0x89, 0x0A);
581 :
582 : // Indirect register only source modes.
583 E : asm_.mov_fs(ebx, OperandImpl(eax));
584 E : EXPECT_BYTES(0x64, 0x8B, 0x18);
585 E : asm_.mov_fs(eax, OperandImpl(ecx));
586 E : EXPECT_BYTES(0x64, 0x8B, 0x01);
587 E : asm_.mov_fs(edx, OperandImpl(ebx));
588 E : EXPECT_BYTES(0x64, 0x8B, 0x13);
589 E : asm_.mov_fs(ecx, OperandImpl(edx));
590 E : EXPECT_BYTES(0x64, 0x8B, 0x0A);
591 E : }
592 :
593 E : TEST_F(AssemblerTest, LeaRegisterIndirect) {
594 : // Indirect register only source modes.
595 E : asm_.lea(ebx, OperandImpl(eax));
596 E : EXPECT_BYTES(0x8D, 0x18);
597 E : asm_.lea(eax, OperandImpl(ecx));
598 E : EXPECT_BYTES(0x8D, 0x01);
599 E : asm_.lea(edx, OperandImpl(ebx));
600 E : EXPECT_BYTES(0x8D, 0x13);
601 E : asm_.lea(ecx, OperandImpl(edx));
602 E : EXPECT_BYTES(0x8D, 0x0A);
603 :
604 : // Note that EBP is a special case that always requires a displacement.
605 E : asm_.lea(ebx, OperandImpl(ebp));
606 E : EXPECT_BYTES(0x8D, 0x5D, 0x00);
607 :
608 : // Note that ESP is a special case that always requires a SIB byte.
609 E : asm_.lea(ecx, OperandImpl(esp));
610 E : EXPECT_BYTES(0x8D, 0x0C, 0x24);
611 :
612 E : asm_.lea(ebx, OperandImpl(esi));
613 E : EXPECT_BYTES(0x8D, 0x1E);
614 E : asm_.lea(eax, OperandImpl(edi));
615 E : EXPECT_BYTES(0x8D, 0x07);
616 E : }
617 :
618 E : TEST_F(AssemblerTest, LeaRegisterDisplacementIndirect) {
619 : // Register & displacement source modes.
620 E : DisplacementImpl cafebabe(0xCAFEBABE, kSize32Bit, NULL);
621 :
622 E : asm_.lea(ebx, OperandImpl(eax, cafebabe));
623 E : EXPECT_BYTES(0x8D, 0x98, 0xBE, 0xBA, 0xFE, 0xCA);
624 E : asm_.lea(eax, OperandImpl(ecx, cafebabe));
625 E : EXPECT_BYTES(0x8D, 0x81, 0xBE, 0xBA, 0xFE, 0xCA);
626 E : asm_.lea(eax, OperandImpl(ebx, cafebabe));
627 E : EXPECT_BYTES(0x8D, 0x83, 0xBE, 0xBA, 0xFE, 0xCA);
628 E : asm_.lea(eax, OperandImpl(edx, cafebabe));
629 E : EXPECT_BYTES(0x8D, 0x82, 0xBE, 0xBA, 0xFE, 0xCA);
630 E : asm_.lea(eax, OperandImpl(ebp, cafebabe));
631 E : EXPECT_BYTES(0x8D, 0x85, 0xBE, 0xBA, 0xFE, 0xCA);
632 :
633 : // ESP requires a SIB byte and has a longer encoding.
634 E : asm_.lea(eax, OperandImpl(esp, cafebabe));
635 E : EXPECT_BYTES(0x8D, 0x84, 0x24, 0xBE, 0xBA, 0xFE, 0xCA);
636 :
637 E : asm_.lea(eax, OperandImpl(esi, cafebabe));
638 E : EXPECT_BYTES(0x8D, 0x86, 0xBE, 0xBA, 0xFE, 0xCA);
639 E : asm_.lea(eax, OperandImpl(edi, cafebabe));
640 E : EXPECT_BYTES(0x8D, 0x87, 0xBE, 0xBA, 0xFE, 0xCA);
641 :
642 : // Test a sampling of 8-bit displacements.
643 E : DisplacementImpl ca(0xCA, kSize8Bit, NULL);
644 :
645 : // Source.
646 E : asm_.lea(ebx, OperandImpl(eax, ca));
647 E : EXPECT_BYTES(0x8D, 0x58, 0xCA);
648 :
649 : // ESP requires a SIB byte and has a longer encoding.
650 E : asm_.lea(eax, OperandImpl(esp, ca));
651 E : EXPECT_BYTES(0x8D, 0x44, 0x24, 0xCA);
652 E : }
653 :
654 E : TEST_F(AssemblerTest, LeaDisplacementIndirect) {
655 : // Displacement-only mode.
656 E : DisplacementImpl cafebabe(0xCAFEBABE, kSize32Bit, NULL);
657 :
658 E : asm_.lea(eax, OperandImpl(cafebabe));
659 E : EXPECT_BYTES(0x8D, 0x05, 0xBE, 0xBA, 0xFE, 0xCA);
660 E : asm_.lea(ecx, OperandImpl(cafebabe));
661 E : EXPECT_BYTES(0x8D, 0x0D, 0xBE, 0xBA, 0xFE, 0xCA);
662 E : }
663 :
664 E : TEST_F(AssemblerTest, LeaRegisterDisplacementScaleIndirect) {
665 : // There are 8 base * 7 index * 4 scales = 224 combinations.
666 : // We don't test all of them, but rather cycle through each of base,
667 : // index and scale individually.
668 E : DisplacementImpl cafebabe(0xCAFEBABE, kSize32Bit, NULL);
669 :
670 : // Source mode, base register.
671 E : asm_.lea(edx, OperandImpl(ecx, eax, kTimes4, cafebabe));
672 E : EXPECT_BYTES(0x8D, 0x94, 0x81, 0xBE, 0xBA, 0xFE, 0xCA);
673 E : asm_.lea(eax, OperandImpl(ecx, eax, kTimes4, cafebabe));
674 E : EXPECT_BYTES(0x8D, 0x84, 0x81, 0xBE, 0xBA, 0xFE, 0xCA);
675 E : asm_.lea(eax, OperandImpl(edx, eax, kTimes4, cafebabe));
676 E : EXPECT_BYTES(0x8D, 0x84, 0x82, 0xBE, 0xBA, 0xFE, 0xCA);
677 E : asm_.lea(eax, OperandImpl(ebx, eax, kTimes4, cafebabe));
678 E : EXPECT_BYTES(0x8D, 0x84, 0x83, 0xBE, 0xBA, 0xFE, 0xCA);
679 E : asm_.lea(eax, OperandImpl(esp, eax, kTimes4, cafebabe));
680 E : EXPECT_BYTES(0x8D, 0x84, 0x84, 0xBE, 0xBA, 0xFE, 0xCA);
681 E : asm_.lea(eax, OperandImpl(ebp, eax, kTimes4, cafebabe));
682 E : EXPECT_BYTES(0x8D, 0x84, 0x85, 0xBE, 0xBA, 0xFE, 0xCA);
683 E : asm_.lea(eax, OperandImpl(esi, eax, kTimes4, cafebabe));
684 E : EXPECT_BYTES(0x8D, 0x84, 0x86, 0xBE, 0xBA, 0xFE, 0xCA);
685 E : asm_.lea(eax, OperandImpl(edi, eax, kTimes4, cafebabe));
686 E : EXPECT_BYTES(0x8D, 0x84, 0x87, 0xBE, 0xBA, 0xFE, 0xCA);
687 :
688 : // Source mode, index register.
689 E : asm_.lea(ebx, OperandImpl(ecx, eax, kTimes4, cafebabe));
690 E : EXPECT_BYTES(0x8D, 0x9C, 0x81, 0xBE, 0xBA, 0xFE, 0xCA);
691 E : asm_.lea(eax, OperandImpl(eax, ecx, kTimes4, cafebabe));
692 E : EXPECT_BYTES(0x8D, 0x84, 0x88, 0xBE, 0xBA, 0xFE, 0xCA);
693 E : asm_.lea(eax, OperandImpl(eax, edx, kTimes4, cafebabe));
694 E : EXPECT_BYTES(0x8D, 0x84, 0x90, 0xBE, 0xBA, 0xFE, 0xCA);
695 E : asm_.lea(eax, OperandImpl(eax, ebx, kTimes4, cafebabe));
696 E : EXPECT_BYTES(0x8D, 0x84, 0x98, 0xBE, 0xBA, 0xFE, 0xCA);
697 E : asm_.lea(eax, OperandImpl(eax, ebp, kTimes4, cafebabe));
698 E : EXPECT_BYTES(0x8D, 0x84, 0xA8, 0xBE, 0xBA, 0xFE, 0xCA);
699 E : asm_.lea(eax, OperandImpl(eax, esi, kTimes4, cafebabe));
700 E : EXPECT_BYTES(0x8D, 0x84, 0xB0, 0xBE, 0xBA, 0xFE, 0xCA);
701 E : asm_.lea(eax, OperandImpl(eax, edi, kTimes4, cafebabe));
702 E : EXPECT_BYTES(0x8D, 0x84, 0xB8, 0xBE, 0xBA, 0xFE, 0xCA);
703 :
704 : // Source mode, Scale.
705 E : asm_.lea(ebx, OperandImpl(ecx, eax, kTimes1, cafebabe));
706 E : EXPECT_BYTES(0x8D, 0x9C, 0x01, 0xBE, 0xBA, 0xFE, 0xCA);
707 E : asm_.lea(ebx, OperandImpl(ecx, eax, kTimes2, cafebabe));
708 E : EXPECT_BYTES(0x8D, 0x9C, 0x41, 0xBE, 0xBA, 0xFE, 0xCA);
709 E : asm_.lea(ebx, OperandImpl(ecx, eax, kTimes4, cafebabe));
710 E : EXPECT_BYTES(0x8D, 0x9C, 0x81, 0xBE, 0xBA, 0xFE, 0xCA);
711 E : asm_.lea(ebx, OperandImpl(ecx, eax, kTimes8, cafebabe));
712 E : EXPECT_BYTES(0x8D, 0x9C, 0xC1, 0xBE, 0xBA, 0xFE, 0xCA);
713 E : }
714 :
715 E : TEST_F(AssemblerTest, Push) {
716 : // Register push.
717 E : asm_.push(eax);
718 E : asm_.push(ecx);
719 E : asm_.push(edx);
720 E : asm_.push(ebx);
721 E : asm_.push(esp);
722 E : asm_.push(ebp);
723 E : asm_.push(esi);
724 E : asm_.push(edi);
725 E : EXPECT_BYTES(0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57);
726 :
727 : // Immediate push.
728 E : asm_.push(ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
729 E : EXPECT_BYTES(0x68, 0xBE, 0xBA, 0xFE, 0xCA);
730 :
731 : // General push, try one variant as the rest are OperandImpl encodings.
732 E : asm_.push(OperandImpl(DisplacementImpl(0xCAFEBABE, kSize32Bit, NULL)));
733 E : EXPECT_BYTES(0xFF, 0x35, 0xBE, 0xBA, 0xFE, 0xCA);
734 E : }
735 :
736 E : TEST_F(AssemblerTest, Pop) {
737 : // Register pop.
738 E : asm_.pop(eax);
739 E : asm_.pop(ecx);
740 E : asm_.pop(edx);
741 E : asm_.pop(ebx);
742 E : asm_.pop(esp);
743 E : asm_.pop(ebp);
744 E : asm_.pop(esi);
745 E : asm_.pop(edi);
746 E : EXPECT_BYTES(0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F);
747 :
748 : // General pop, try one variant as the rest are OperandImpl encodings.
749 E : asm_.pop(OperandImpl(DisplacementImpl(0xCAFEBABE, kSize32Bit, NULL)));
750 E : EXPECT_BYTES(0x8F, 0x05, 0xBE, 0xBA, 0xFE, 0xCA);
751 E : }
752 :
753 E : TEST_F(AssemblerTest, Flags) {
754 E : asm_.pushfd();
755 E : asm_.popfd();
756 E : asm_.lahf();
757 E : asm_.sahf();
758 E : EXPECT_BYTES(0x9C, 0x9D, 0x9F, 0x9E);
759 E : }
760 :
761 E : TEST_F(AssemblerTest, TestByte) {
762 E : asm_.test(al, bl);
763 E : EXPECT_BYTES(0x84, 0xC3);
764 E : asm_.test(bh, al);
765 E : EXPECT_BYTES(0x84, 0xF8);
766 :
767 E : asm_.test(al, ImmediateImpl(0x0A, kSize8Bit));
768 E : EXPECT_BYTES(0xA8, 0x0A);
769 E : asm_.test(bh, ImmediateImpl(0x0A, kSize8Bit));
770 E : EXPECT_BYTES(0xF6, 0xC7, 0x0A);
771 E : }
772 :
773 E : TEST_F(AssemblerTest, Test) {
774 E : asm_.test(eax, ecx);
775 E : EXPECT_BYTES(0x85, 0xC1);
776 E : asm_.test(ecx, OperandImpl(eax));
777 E : EXPECT_BYTES(0x85, 0x08);
778 E : asm_.test(ecx, OperandImpl(eax, DisplacementImpl(10, kSize8Bit)));
779 E : EXPECT_BYTES(0x85, 0x48, 0x0A);
780 E : asm_.test(ecx, OperandImpl(eax, DisplacementImpl(10, kSize32Bit)));
781 E : EXPECT_BYTES(0x85, 0x88, 0x0A, 0x00, 0x00, 0x00);
782 :
783 E : asm_.test(ecx, eax);
784 E : EXPECT_BYTES(0x85, 0xC8);
785 E : asm_.test(ecx, OperandImpl(eax));
786 E : EXPECT_BYTES(0x85, 0x08);
787 E : asm_.test(ecx, OperandImpl(eax, DisplacementImpl(10, kSize8Bit)));
788 E : EXPECT_BYTES(0x85, 0x48, 0x0A);
789 E : asm_.test(ecx, OperandImpl(eax, DisplacementImpl(10, kSize32Bit)));
790 E : EXPECT_BYTES(0x85, 0x88, 0x0A, 0x00, 0x00, 0x00);
791 :
792 E : asm_.test(OperandImpl(eax), ecx);
793 E : EXPECT_BYTES(0x85, 0x08);
794 E : asm_.test(OperandImpl(eax, DisplacementImpl(10, kSize8Bit)), ecx);
795 E : EXPECT_BYTES(0x85, 0x48, 0x0A);
796 E : asm_.test(OperandImpl(eax, DisplacementImpl(10, kSize32Bit)), ecx);
797 E : EXPECT_BYTES(0x85, 0x88, 0x0A, 0x00, 0x00, 0x00);
798 :
799 E : asm_.test(eax, ImmediateImpl(0x0A, kSize8Bit));
800 E : EXPECT_BYTES(0xA9, 0x0A, 0x00, 0x00, 0x00);
801 E : asm_.test(ecx, ImmediateImpl(0x0A, kSize8Bit));
802 E : EXPECT_BYTES(0xF7, 0xC1, 0x0A, 0x00, 0x00, 0x00);
803 E : asm_.test(ecx, ImmediateImpl(0xDEADBEEF, kSize32Bit));
804 E : EXPECT_BYTES(0xF7, 0xC1, 0xEF, 0xBE, 0xAD, 0xDE);
805 :
806 E : asm_.test(OperandImpl(eax), ImmediateImpl(1, kSize8Bit));
807 E : EXPECT_BYTES(0xF7, 0x00, 0x01, 0x00, 0x00, 0x00);
808 E : asm_.test(OperandImpl(eax), ImmediateImpl(0xDEADBEEF, kSize32Bit));
809 E : EXPECT_BYTES(0xF7, 0x00, 0xEF, 0xBE, 0xAD, 0xDE);
810 : asm_.test(OperandImpl(eax, DisplacementImpl(10, kSize8Bit)),
811 E : ImmediateImpl(0x1, kSize8Bit));
812 E : EXPECT_BYTES(0xF7, 0x40, 0x0A, 0x01, 0x00, 0x00, 0x00);
813 : asm_.test(OperandImpl(eax, DisplacementImpl(10, kSize8Bit)),
814 E : ImmediateImpl(0xDEADBEEF, kSize32Bit));
815 E : EXPECT_BYTES(0xF7, 0x40, 0x0A, 0xEF, 0xBE, 0xAD, 0xDE);
816 : asm_.test(OperandImpl(eax, DisplacementImpl(10, kSize32Bit)),
817 E : ImmediateImpl(0xDEADBEEF, kSize32Bit));
818 E : EXPECT_BYTES(0xF7, 0x80, 0x0A, 0x00, 0x00, 0x00, 0xEF, 0xBE, 0xAD, 0xDE);
819 :
820 : // Special EAX mode + immediate.
821 E : asm_.test(eax, ImmediateImpl(0xDEADBEEF, kSize32Bit));
822 E : EXPECT_BYTES(0xA9, 0xEF, 0xBE, 0xAD, 0xDE);
823 E : }
824 :
825 E : TEST_F(AssemblerTest, CmpByte) {
826 E : asm_.cmp(al, bl);
827 E : EXPECT_BYTES(0x3A, 0xC3);
828 E : asm_.cmp(bh, al);
829 E : EXPECT_BYTES(0x3A, 0xF8);
830 :
831 E : asm_.cmp(al, ImmediateImpl(0x0A, kSize8Bit));
832 E : EXPECT_BYTES(0x3C, 0x0A);
833 E : asm_.cmp(bh, ImmediateImpl(0x0A, kSize8Bit));
834 E : EXPECT_BYTES(0x80, 0xFF, 0x0A);
835 E : }
836 :
837 E : TEST_F(AssemblerTest, Cmp) {
838 E : asm_.cmp(eax, ecx);
839 E : EXPECT_BYTES(0x3B, 0xC1);
840 E : asm_.cmp(ecx, OperandImpl(eax));
841 E : EXPECT_BYTES(0x3B, 0x08);
842 E : asm_.cmp(ecx, OperandImpl(eax, DisplacementImpl(10, kSize8Bit)));
843 E : EXPECT_BYTES(0x3B, 0x48, 0x0A);
844 E : asm_.cmp(ecx, OperandImpl(eax, DisplacementImpl(10, kSize32Bit)));
845 E : EXPECT_BYTES(0x3B, 0x88, 0x0A, 0x00, 0x00, 0x00);
846 :
847 E : asm_.cmp(ecx, eax);
848 E : EXPECT_BYTES(0x3B, 0xC8);
849 E : asm_.cmp(ecx, OperandImpl(eax));
850 E : EXPECT_BYTES(0x3B, 0x08);
851 E : asm_.cmp(ecx, OperandImpl(eax, DisplacementImpl(10, kSize8Bit)));
852 E : EXPECT_BYTES(0x3B, 0x48, 0x0A);
853 E : asm_.cmp(ecx, OperandImpl(eax, DisplacementImpl(10, kSize32Bit)));
854 E : EXPECT_BYTES(0x3B, 0x88, 0x0A, 0x00, 0x00, 0x00);
855 :
856 E : asm_.cmp(OperandImpl(eax), ecx);
857 E : EXPECT_BYTES(0x39, 0x08);
858 E : asm_.cmp(OperandImpl(eax, DisplacementImpl(10, kSize8Bit)), ecx);
859 E : EXPECT_BYTES(0x39, 0x48, 0x0A);
860 E : asm_.cmp(OperandImpl(eax, DisplacementImpl(10, kSize32Bit)), ecx);
861 E : EXPECT_BYTES(0x39, 0x88, 0x0A, 0x00, 0x00, 0x00);
862 :
863 E : asm_.cmp(eax, ImmediateImpl(0x0A, kSize8Bit));
864 E : EXPECT_BYTES(0x83, 0xF8, 0x0A);
865 E : asm_.cmp(ecx, ImmediateImpl(0x0A, kSize8Bit));
866 E : EXPECT_BYTES(0x83, 0xF9, 0x0A);
867 E : asm_.cmp(ecx, ImmediateImpl(0xDEADBEEF, kSize32Bit));
868 E : EXPECT_BYTES(0x81, 0xF9, 0xEF, 0xBE, 0xAD, 0xDE);
869 :
870 E : asm_.cmp(OperandImpl(eax), ImmediateImpl(1, kSize8Bit));
871 E : EXPECT_BYTES(0x83, 0x38, 0x01);
872 E : asm_.cmp(OperandImpl(eax), ImmediateImpl(0xDEADBEEF, kSize32Bit));
873 E : EXPECT_BYTES(0x81, 0x38, 0xEF, 0xBE, 0xAD, 0xDE);
874 : asm_.cmp(OperandImpl(eax, DisplacementImpl(10, kSize8Bit)),
875 E : ImmediateImpl(0x1, kSize8Bit));
876 E : EXPECT_BYTES(0x83, 0x78, 0x0A, 0x1);
877 : asm_.cmp(OperandImpl(eax, DisplacementImpl(10, kSize8Bit)),
878 E : ImmediateImpl(0xDEADBEEF, kSize32Bit));
879 E : EXPECT_BYTES(0x81, 0x78, 0x0A, 0xEF, 0xBE, 0xAD, 0xDE);
880 : asm_.cmp(OperandImpl(eax, DisplacementImpl(10, kSize32Bit)),
881 E : ImmediateImpl(0xDEADBEEF, kSize32Bit));
882 E : EXPECT_BYTES(0x81, 0xB8, 0x0A, 0x00, 0x00, 0x00, 0xEF, 0xBE, 0xAD, 0xDE);
883 :
884 : // Special EAX mode + immediate.
885 E : asm_.cmp(eax, ImmediateImpl(0xDEADBEEF, kSize32Bit));
886 E : EXPECT_BYTES(0x3D, 0xEF, 0xBE, 0xAD, 0xDE);
887 E : }
888 :
889 E : TEST_F(AssemblerTest, AddByte) {
890 E : asm_.add(al, bl);
891 E : EXPECT_BYTES(0x02, 0xC3);
892 E : asm_.add(bh, al);
893 E : EXPECT_BYTES(0x02, 0xF8);
894 :
895 E : asm_.add(al, ImmediateImpl(0x0A, kSize8Bit));
896 E : EXPECT_BYTES(0x04, 0x0A);
897 E : asm_.add(bh, ImmediateImpl(0x0A, kSize8Bit));
898 E : EXPECT_BYTES(0x80, 0xC7, 0x0A);
899 E : }
900 :
901 :
902 E : TEST_F(AssemblerTest, Add) {
903 E : asm_.add(eax, eax);
904 E : EXPECT_BYTES(0x03, 0xC0);
905 E : asm_.add(eax, OperandImpl(eax));
906 E : EXPECT_BYTES(0x03, 0x00);
907 E : asm_.add(eax, OperandImpl(eax, DisplacementImpl(10, kSize8Bit)));
908 E : EXPECT_BYTES(0x03, 0x40, 0x0A);
909 E : asm_.add(eax, OperandImpl(eax, DisplacementImpl(10, kSize32Bit)));
910 E : EXPECT_BYTES(0x03, 0x80, 0x0A, 0x00, 0x00, 0x00);
911 :
912 E : asm_.add(ecx, eax);
913 E : EXPECT_BYTES(0x03, 0xC8);
914 E : asm_.add(ecx, OperandImpl(eax));
915 E : EXPECT_BYTES(0x03, 0x08);
916 E : asm_.add(ecx, OperandImpl(eax, DisplacementImpl(10, kSize8Bit)));
917 E : EXPECT_BYTES(0x03, 0x48, 0x0A);
918 E : asm_.add(ecx, OperandImpl(eax, DisplacementImpl(10, kSize32Bit)));
919 E : EXPECT_BYTES(0x03, 0x88, 0x0A, 0x00, 0x00, 0x00);
920 :
921 E : asm_.add(eax, ecx);
922 E : EXPECT_BYTES(0x03, 0xC1);
923 E : asm_.add(OperandImpl(eax), ecx);
924 E : EXPECT_BYTES(0x01, 0x08);
925 E : asm_.add(OperandImpl(eax, DisplacementImpl(10, kSize8Bit)), ecx);
926 E : EXPECT_BYTES(0x01, 0x48, 0x0A);
927 E : asm_.add(OperandImpl(eax, DisplacementImpl(10, kSize32Bit)), ecx);
928 E : EXPECT_BYTES(0x01, 0x88, 0x0A, 0x00, 0x00, 0x00);
929 :
930 E : asm_.add(eax, ImmediateImpl(0x0A, kSize8Bit));
931 E : EXPECT_BYTES(0x83, 0xC0, 0x0A);
932 E : asm_.add(ecx, ImmediateImpl(0x0A, kSize8Bit));
933 E : EXPECT_BYTES(0x83, 0xC1, 0x0A);
934 E : asm_.add(ecx, ImmediateImpl(0xDEADBEEF, kSize32Bit));
935 E : EXPECT_BYTES(0x81, 0xC1, 0xEF, 0xBE, 0xAD, 0xDE);
936 :
937 E : asm_.add(OperandImpl(eax), ImmediateImpl(1, kSize8Bit));
938 E : EXPECT_BYTES(0x83, 0x00, 0x01);
939 E : asm_.add(OperandImpl(eax), ImmediateImpl(0xDEADBEEF, kSize32Bit));
940 E : EXPECT_BYTES(0x81, 0x00, 0xEF, 0xBE, 0xAD, 0xDE);
941 : asm_.add(OperandImpl(eax, DisplacementImpl(10, kSize8Bit)),
942 E : ImmediateImpl(0xDEADBEEF, kSize32Bit));
943 E : EXPECT_BYTES(0x81, 0x40, 0x0A, 0xEF, 0xBE, 0xAD, 0xDE);
944 : asm_.add(OperandImpl(eax, DisplacementImpl(10, kSize32Bit)),
945 E : ImmediateImpl(0xDEADBEEF, kSize32Bit));
946 E : EXPECT_BYTES(0x81, 0x80, 0x0A, 0x00, 0x00, 0x00, 0xEF, 0xBE, 0xAD, 0xDE);
947 :
948 : // Special EAX mode + immediate.
949 E : asm_.add(eax, ImmediateImpl(0xDEADBEEF, kSize32Bit));
950 E : EXPECT_BYTES(0x05, 0xEF, 0xBE, 0xAD, 0xDE);
951 E : }
952 :
953 E : TEST_F(AssemblerTest, SubByte) {
954 E : asm_.sub(al, bl);
955 E : EXPECT_BYTES(0x2A, 0xC3);
956 E : asm_.sub(bh, al);
957 E : EXPECT_BYTES(0x2A, 0xF8);
958 :
959 E : asm_.sub(al, ImmediateImpl(0x0A, kSize8Bit));
960 E : EXPECT_BYTES(0x2C, 0x0A);
961 E : asm_.sub(bh, ImmediateImpl(0x0A, kSize8Bit));
962 E : EXPECT_BYTES(0x80, 0xEF, 0x0A);
963 E : }
964 :
965 E : TEST_F(AssemblerTest, Sub) {
966 E : asm_.sub(eax, eax);
967 E : EXPECT_BYTES(0x2B, 0xC0);
968 E : asm_.sub(eax, OperandImpl(eax));
969 E : EXPECT_BYTES(0x2B, 0x00);
970 E : asm_.sub(eax, OperandImpl(eax, DisplacementImpl(10, kSize8Bit)));
971 E : EXPECT_BYTES(0x2B, 0x40, 0x0A);
972 E : asm_.sub(eax, OperandImpl(eax, DisplacementImpl(10, kSize32Bit)));
973 E : EXPECT_BYTES(0x2B, 0x80, 0x0A, 0x00, 0x00, 0x00);
974 :
975 E : asm_.sub(ecx, eax);
976 E : EXPECT_BYTES(0x2B, 0xC8);
977 E : asm_.sub(ecx, OperandImpl(eax));
978 E : EXPECT_BYTES(0x2B, 0x08);
979 E : asm_.sub(ecx, OperandImpl(eax, DisplacementImpl(10, kSize8Bit)));
980 E : EXPECT_BYTES(0x2B, 0x48, 0x0A);
981 E : asm_.sub(ecx, OperandImpl(eax, DisplacementImpl(10, kSize32Bit)));
982 E : EXPECT_BYTES(0x2B, 0x88, 0x0A, 0x00, 0x00, 0x00);
983 :
984 E : asm_.sub(eax, ecx);
985 E : EXPECT_BYTES(0x2B, 0xC1);
986 E : asm_.sub(OperandImpl(eax), ecx);
987 E : EXPECT_BYTES(0x29, 0x08);
988 E : asm_.sub(OperandImpl(eax, DisplacementImpl(10, kSize8Bit)), ecx);
989 E : EXPECT_BYTES(0x29, 0x48, 0x0A);
990 E : asm_.sub(OperandImpl(eax, DisplacementImpl(10, kSize32Bit)), ecx);
991 E : EXPECT_BYTES(0x29, 0x88, 0x0A, 0x00, 0x00, 0x00);
992 :
993 E : asm_.sub(eax, ImmediateImpl(0x0A, kSize8Bit));
994 E : EXPECT_BYTES(0x83, 0xE8, 0x0A);
995 E : asm_.sub(ecx, ImmediateImpl(0x0A, kSize8Bit));
996 E : EXPECT_BYTES(0x83, 0xE9, 0x0A);
997 E : asm_.sub(ecx, ImmediateImpl(0xDEADBEEF, kSize32Bit));
998 E : EXPECT_BYTES(0x81, 0xE9, 0xEF, 0xBE, 0xAD, 0xDE);
999 :
1000 E : asm_.sub(OperandImpl(eax), ImmediateImpl(0x1, kSize8Bit));
1001 E : EXPECT_BYTES(0x83, 0x28, 0x01);
1002 E : asm_.sub(OperandImpl(eax), ImmediateImpl(0xDEADBEEF, kSize32Bit));
1003 E : EXPECT_BYTES(0x81, 0x28, 0xEF, 0xBE, 0xAD, 0xDE);
1004 : asm_.sub(OperandImpl(eax, DisplacementImpl(10, kSize8Bit)),
1005 E : ImmediateImpl(0xDEADBEEF, kSize32Bit));
1006 E : EXPECT_BYTES(0x81, 0x68, 0x0A, 0xEF, 0xBE, 0xAD, 0xDE);
1007 : asm_.sub(OperandImpl(eax, DisplacementImpl(10, kSize32Bit)),
1008 E : ImmediateImpl(0xDEADBEEF, kSize32Bit));
1009 E : EXPECT_BYTES(0x81, 0xA8, 0x0A, 0x00, 0x00, 0x00, 0xEF, 0xBE, 0xAD, 0xDE);
1010 :
1011 : // Special EAX mode + immediate.
1012 E : asm_.sub(eax, ImmediateImpl(0xDEADBEEF, kSize32Bit));
1013 E : EXPECT_BYTES(0x2D, 0xEF, 0xBE, 0xAD, 0xDE);
1014 E : }
1015 :
1016 E : TEST_F(AssemblerTest, Shl) {
1017 E : asm_.shl(eax, ImmediateImpl(0x1, kSize8Bit));
1018 E : EXPECT_BYTES(0xD1, 0xE0);
1019 E : asm_.shl(eax, ImmediateImpl(0x3, kSize8Bit));
1020 E : EXPECT_BYTES(0xC1, 0xE0, 0x03);
1021 E : asm_.shl(ecx, ImmediateImpl(0x1, kSize8Bit));
1022 E : EXPECT_BYTES(0xD1, 0xE1);
1023 E : asm_.shl(ecx, ImmediateImpl(0x3, kSize8Bit));
1024 E : EXPECT_BYTES(0xC1, 0xE1, 0x03);
1025 E : }
1026 :
1027 E : TEST_F(AssemblerTest, Shr) {
1028 E : asm_.shr(eax, ImmediateImpl(0x1, kSize8Bit));
1029 E : EXPECT_BYTES(0xD1, 0xE8);
1030 E : asm_.shr(eax, ImmediateImpl(0x3, kSize8Bit));
1031 E : EXPECT_BYTES(0xC1, 0xE8, 0x03);
1032 E : asm_.shr(ecx, ImmediateImpl(0x1, kSize8Bit));
1033 E : EXPECT_BYTES(0xD1, 0xE9);
1034 E : asm_.shr(ecx, ImmediateImpl(0x3, kSize8Bit));
1035 E : EXPECT_BYTES(0xC1, 0xE9, 0x03);
1036 E : }
1037 :
1038 E : TEST_F(AssemblerTest, Xchg32) {
1039 : // Any exchange with the eax register should generate a single byte
1040 : // instruction.
1041 E : asm_.xchg(eax, eax);
1042 E : EXPECT_BYTES(0x90);
1043 E : asm_.xchg(eax, ecx);
1044 E : EXPECT_BYTES(0x91);
1045 E : asm_.xchg(esp, eax);
1046 E : EXPECT_BYTES(0x94);
1047 :
1048 : // Any exchanges not involving the eax register should generate 2-byte
1049 : // instructions.
1050 E : asm_.xchg(ebx, ecx);
1051 E : EXPECT_BYTES(0x87, 0xCB);
1052 E : asm_.xchg(edx, esp);
1053 E : EXPECT_BYTES(0x87, 0xE2);
1054 E : asm_.xchg(esp, edx);
1055 E : EXPECT_BYTES(0x87, 0xD4);
1056 E : }
1057 :
1058 E : TEST_F(AssemblerTest, Xchg16) {
1059 : // Any exchange with the ax register should generate 2-byte instructions.
1060 E : asm_.xchg(ax, ax);
1061 E : EXPECT_BYTES(0x66, 0x90);
1062 E : asm_.xchg(ax, cx);
1063 E : EXPECT_BYTES(0x66, 0x91);
1064 E : asm_.xchg(sp, ax);
1065 E : EXPECT_BYTES(0x66, 0x94);
1066 :
1067 : // Any exchanges not involving the ax register should generate 3-byte
1068 : // instructions.
1069 E : asm_.xchg(cx, dx);
1070 E : EXPECT_BYTES(0x66, 0x87, 0xD1);
1071 E : asm_.xchg(bx, cx);
1072 E : EXPECT_BYTES(0x66, 0x87, 0xCB);
1073 E : asm_.xchg(dx, sp);
1074 E : EXPECT_BYTES(0x66, 0x87, 0xE2);
1075 E : asm_.xchg(sp, dx);
1076 E : EXPECT_BYTES(0x66, 0x87, 0xD4);
1077 E : asm_.xchg(bp, dx);
1078 E : EXPECT_BYTES(0x66, 0x87, 0xD5);
1079 E : asm_.xchg(si, sp);
1080 E : EXPECT_BYTES(0x66, 0x87, 0xE6);
1081 E : asm_.xchg(di, cx);
1082 E : EXPECT_BYTES(0x66, 0x87, 0xCF);
1083 E : }
1084 :
1085 E : TEST_F(AssemblerTest, Xchg8) {
1086 E : asm_.xchg(al, ah);
1087 E : EXPECT_BYTES(0x86, 0xE0);
1088 E : asm_.xchg(cl, bl);
1089 E : EXPECT_BYTES(0x86, 0xD9);
1090 E : asm_.xchg(dl, bh);
1091 E : EXPECT_BYTES(0x86, 0xFA);
1092 E : asm_.xchg(bl, dh);
1093 E : EXPECT_BYTES(0x86, 0xF3);
1094 E : asm_.xchg(ah, cl);
1095 E : EXPECT_BYTES(0x86, 0xCC);
1096 E : asm_.xchg(ch, dl);
1097 E : EXPECT_BYTES(0x86, 0xD5);
1098 E : asm_.xchg(dh, ch);
1099 E : EXPECT_BYTES(0x86, 0xEE);
1100 E : asm_.xchg(bh, al);
1101 E : EXPECT_BYTES(0x86, 0xC7);
1102 E : }
1103 :
1104 E : TEST_F(AssemblerTest, Ja) {
1105 E : ConditionCode cc = kAbove;
1106 E : asm_.set_location(0xCAFEBABE);
1107 :
1108 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
1109 E : EXPECT_BYTES(0x77, 0xFE);
1110 :
1111 E : ASSERT_EQ(1, AssemblerImpl::kShortBranchOpcodeSize);
1112 E : ASSERT_EQ(2, AssemblerImpl::kShortBranchSize);
1113 :
1114 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
1115 E : EXPECT_BYTES(0x0F, 0x87, 0xF8, 0xFF, 0xFF, 0xFF);
1116 :
1117 E : ASSERT_EQ(2, AssemblerImpl::kLongBranchOpcodeSize);
1118 E : ASSERT_EQ(6, AssemblerImpl::kLongBranchSize);
1119 E : }
1120 :
1121 E : TEST_F(AssemblerTest, Jae) {
1122 E : ConditionCode cc = kAboveEqual;
1123 E : asm_.set_location(0xCAFEBABE);
1124 :
1125 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
1126 E : EXPECT_BYTES(0x73, 0xFE);
1127 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
1128 E : EXPECT_BYTES(0x0F, 0x83, 0xF8, 0xFF, 0xFF, 0xFF);
1129 E : }
1130 :
1131 E : TEST_F(AssemblerTest, Jb) {
1132 E : ConditionCode cc = kBelow;
1133 E : asm_.set_location(0xCAFEBABE);
1134 :
1135 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
1136 E : EXPECT_BYTES(0x72, 0xFE);
1137 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
1138 E : EXPECT_BYTES(0x0F, 0x82, 0xF8, 0xFF, 0xFF, 0xFF);
1139 E : }
1140 :
1141 E : TEST_F(AssemblerTest, Jbe) {
1142 E : ConditionCode cc = kBelowEqual;
1143 E : asm_.set_location(0xCAFEBABE);
1144 :
1145 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
1146 E : EXPECT_BYTES(0x76, 0xFE);
1147 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
1148 E : EXPECT_BYTES(0x0F, 0x86, 0xF8, 0xFF, 0xFF, 0xFF);
1149 E : }
1150 :
1151 E : TEST_F(AssemblerTest, Jc) {
1152 E : ConditionCode cc = kCarry;
1153 E : asm_.set_location(0xCAFEBABE);
1154 :
1155 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
1156 E : EXPECT_BYTES(0x72, 0xFE);
1157 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
1158 E : EXPECT_BYTES(0x0F, 0x82, 0xF8, 0xFF, 0xFF, 0xFF);
1159 E : }
1160 :
1161 E : TEST_F(AssemblerTest, Je) {
1162 E : ConditionCode cc = kEqual;
1163 E : asm_.set_location(0xCAFEBABE);
1164 :
1165 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
1166 E : EXPECT_BYTES(0x74, 0xFE);
1167 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
1168 E : EXPECT_BYTES(0x0F, 0x84, 0xF8, 0xFF, 0xFF, 0xFF);
1169 E : }
1170 :
1171 E : TEST_F(AssemblerTest, Jecxz) {
1172 E : asm_.set_location(0xCAFEBABE);
1173 :
1174 E : asm_.jecxz(ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
1175 E : EXPECT_BYTES(0xE3, 0xFE);
1176 E : }
1177 :
1178 E : TEST_F(AssemblerTest, Jg) {
1179 E : ConditionCode cc = kGreater;
1180 E : asm_.set_location(0xCAFEBABE);
1181 :
1182 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
1183 E : EXPECT_BYTES(0x7F, 0xFE);
1184 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
1185 E : EXPECT_BYTES(0x0F, 0x8F, 0xF8, 0xFF, 0xFF, 0xFF);
1186 E : }
1187 :
1188 E : TEST_F(AssemblerTest, Jge) {
1189 E : ConditionCode cc = kGreaterEqual;
1190 E : asm_.set_location(0xCAFEBABE);
1191 :
1192 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
1193 E : EXPECT_BYTES(0x7D, 0xFE);
1194 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
1195 E : EXPECT_BYTES(0x0F, 0x8D, 0xF8, 0xFF, 0xFF, 0xFF);
1196 E : }
1197 :
1198 E : TEST_F(AssemblerTest, Jl) {
1199 E : ConditionCode cc = kLess;
1200 E : asm_.set_location(0xCAFEBABE);
1201 :
1202 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
1203 E : EXPECT_BYTES(0x7C, 0xFE);
1204 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
1205 E : EXPECT_BYTES(0x0F, 0x8C, 0xF8, 0xFF, 0xFF, 0xFF);
1206 E : }
1207 :
1208 E : TEST_F(AssemblerTest, Jle) {
1209 E : ConditionCode cc = kLessEqual;
1210 E : asm_.set_location(0xCAFEBABE);
1211 :
1212 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
1213 E : EXPECT_BYTES(0x7E, 0xFE);
1214 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
1215 E : EXPECT_BYTES(0x0F, 0x8E, 0xF8, 0xFF, 0xFF, 0xFF);
1216 E : }
1217 :
1218 E : TEST_F(AssemblerTest, Jo) {
1219 E : ConditionCode cc = kOverflow;
1220 E : asm_.set_location(0xCAFEBABE);
1221 :
1222 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
1223 E : EXPECT_BYTES(0x70, 0xFE);
1224 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
1225 E : EXPECT_BYTES(0x0F, 0x80, 0xF8, 0xFF, 0xFF, 0xFF);
1226 E : }
1227 :
1228 E : TEST_F(AssemblerTest, Jpe) {
1229 E : ConditionCode cc = kParityEven;
1230 E : asm_.set_location(0xCAFEBABE);
1231 :
1232 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
1233 E : EXPECT_BYTES(0x7A, 0xFE);
1234 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
1235 E : EXPECT_BYTES(0x0F, 0x8A, 0xF8, 0xFF, 0xFF, 0xFF);
1236 E : }
1237 :
1238 E : TEST_F(AssemblerTest, Jpo) {
1239 E : ConditionCode cc = kParityOdd;
1240 E : asm_.set_location(0xCAFEBABE);
1241 :
1242 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
1243 E : EXPECT_BYTES(0x7B, 0xFE);
1244 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
1245 E : EXPECT_BYTES(0x0F, 0x8B, 0xF8, 0xFF, 0xFF, 0xFF);
1246 E : }
1247 :
1248 E : TEST_F(AssemblerTest, Js) {
1249 E : ConditionCode cc = kSign;
1250 E : asm_.set_location(0xCAFEBABE);
1251 : COMPILE_ASSERT(kSign == kNegative, kSignAndPositiveAreAliases);
1252 :
1253 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
1254 E : EXPECT_BYTES(0x78, 0xFE);
1255 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
1256 E : EXPECT_BYTES(0x0F, 0x88, 0xF8, 0xFF, 0xFF, 0xFF);
1257 E : }
1258 :
1259 E : TEST_F(AssemblerTest, Jz) {
1260 E : ConditionCode cc = kZero;
1261 E : asm_.set_location(0xCAFEBABE);
1262 :
1263 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
1264 E : EXPECT_BYTES(0x74, 0xFE);
1265 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
1266 E : EXPECT_BYTES(0x0F, 0x84, 0xF8, 0xFF, 0xFF, 0xFF);
1267 E : }
1268 :
1269 E : TEST_F(AssemblerTest, Jnc) {
1270 E : ConditionCode cc = kNotCarry;
1271 E : asm_.set_location(0xCAFEBABE);
1272 :
1273 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
1274 E : EXPECT_BYTES(0x73, 0xFE);
1275 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
1276 E : EXPECT_BYTES(0x0F, 0x83, 0xF8, 0xFF, 0xFF, 0xFF);
1277 E : }
1278 :
1279 E : TEST_F(AssemblerTest, Jne) {
1280 E : ConditionCode cc = kNotEqual;
1281 E : asm_.set_location(0xCAFEBABE);
1282 :
1283 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
1284 E : EXPECT_BYTES(0x75, 0xFE);
1285 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
1286 E : EXPECT_BYTES(0x0F, 0x85, 0xF8, 0xFF, 0xFF, 0xFF);
1287 E : }
1288 :
1289 E : TEST_F(AssemblerTest, Jno) {
1290 E : ConditionCode cc = kNoOverflow;
1291 E : asm_.set_location(0xCAFEBABE);
1292 :
1293 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
1294 E : EXPECT_BYTES(0x71, 0xFE);
1295 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
1296 E : EXPECT_BYTES(0x0F, 0x81, 0xF8, 0xFF, 0xFF, 0xFF);
1297 E : }
1298 :
1299 E : TEST_F(AssemblerTest, Jns) {
1300 : COMPILE_ASSERT(kNotSign == kPositive, kSignAndPositiveAreAliases);
1301 E : ConditionCode cc = kNotSign;
1302 E : asm_.set_location(0xCAFEBABE);
1303 :
1304 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
1305 E : EXPECT_BYTES(0x79, 0xFE);
1306 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
1307 E : EXPECT_BYTES(0x0F, 0x89, 0xF8, 0xFF, 0xFF, 0xFF);
1308 E : }
1309 :
1310 E : TEST_F(AssemblerTest, Jnz) {
1311 E : ConditionCode cc = kNotZero;
1312 E : asm_.set_location(0xCAFEBABE);
1313 :
1314 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
1315 E : EXPECT_BYTES(0x75, 0xFE);
1316 E : asm_.j(cc, ImmediateImpl(0xCAFEBABE, kSize32Bit, NULL));
1317 E : EXPECT_BYTES(0x0F, 0x85, 0xF8, 0xFF, 0xFF, 0xFF);
1318 E : }
1319 :
1320 E : TEST_F(AssemblerTest, Seto) {
1321 E : asm_.set_location(0xCAFEBABE);
1322 E : asm_.set(kOverflow, core::eax);
1323 E : EXPECT_BYTES(0x0F, 0x90, 0xC0);
1324 E : }
1325 :
1326 E : TEST_F(AssemblerTest, Setno) {
1327 E : asm_.set(kNoOverflow, core::ebx);
1328 E : EXPECT_BYTES(0x0F, 0x91, 0xC3);
1329 E : }
1330 :
1331 E : TEST_F(AssemblerTest, Sete) {
1332 E : asm_.set(kEqual, core::eax);
1333 E : EXPECT_BYTES(0x0F, 0x94, 0xC0);
1334 E : }
1335 :
1336 E : TEST_F(AssemblerTest, Setne) {
1337 E : asm_.set(kNotEqual, core::eax);
1338 E : EXPECT_BYTES(0x0F, 0x95, 0xC0);
1339 E : }
1340 :
1341 E : TEST_F(AssemblerTest, Setb) {
1342 E : asm_.set(kBelow, core::eax);
1343 E : EXPECT_BYTES(0x0F, 0x92, 0xC0);
1344 E : }
1345 :
1346 E : TEST_F(AssemblerTest, Loop) {
1347 E : asm_.set_location(0xCAFEBABE);
1348 :
1349 E : asm_.loop(ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
1350 E : EXPECT_BYTES(0xE2, 0xFE);
1351 E : }
1352 :
1353 E : TEST_F(AssemblerTest, Loope) {
1354 E : asm_.set_location(0xCAFEBABE);
1355 :
1356 E : asm_.loope(ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
1357 E : EXPECT_BYTES(0xE1, 0xFE);
1358 E : }
1359 :
1360 E : TEST_F(AssemblerTest, Loopne) {
1361 E : asm_.set_location(0xCAFEBABE);
1362 :
1363 E : asm_.loopne(ImmediateImpl(0xCAFEBABE, kSize8Bit, NULL));
1364 E : EXPECT_BYTES(0xE0, 0xFE);
1365 E : }
1366 :
1367 E : TEST_F(AssemblerTest, References) {
1368 : // We arbitrarily use the MOV instruction to test reference propagation.
1369 : static const int ref1 = 1;
1370 E : asm_.mov(eax, ImmediateImpl(0, kSize8Bit, &ref1));
1371 :
1372 : static const int ref2 = 2;
1373 : asm_.mov(eax, OperandImpl(eax, ebx, kTimes4,
1374 E : DisplacementImpl(0, kSize32Bit, &ref2)));
1375 :
1376 : static const int ref3 = 3;
1377 : static const int ref4 = 4;
1378 : asm_.mov(OperandImpl(eax, ebx, kTimes4,
1379 : DisplacementImpl(0, kSize32Bit, &ref3)),
1380 E : ImmediateImpl(0, kSize32Bit, &ref4));
1381 :
1382 E : EXPECT_EQ(4, serializer_.references.size());
1383 :
1384 E : EXPECT_EQ(1, serializer_.references[0].location);
1385 E : EXPECT_EQ(&ref1, serializer_.references[0].ref);
1386 :
1387 E : EXPECT_EQ(8, serializer_.references[1].location);
1388 E : EXPECT_EQ(&ref2, serializer_.references[1].ref);
1389 :
1390 E : EXPECT_EQ(15, serializer_.references[2].location);
1391 E : EXPECT_EQ(&ref3, serializer_.references[2].ref);
1392 :
1393 E : EXPECT_EQ(19, serializer_.references[3].location);
1394 E : EXPECT_EQ(&ref4, serializer_.references[3].ref);
1395 E : }
1396 :
1397 : } // namespace core
|