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