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/block_graph/basic_block_assembler.h"
16 :
17 : namespace block_graph {
18 :
19 : namespace {
20 :
21 : typedef core::DisplacementImpl DisplacementImpl;
22 : typedef core::OperandImpl OperandImpl;
23 : typedef core::ValueImpl ValueImpl;
24 : typedef core::ValueSize ValueSize;
25 :
26 E : ValueSize ValueSizeFromConstant(uint32 input_value) {
27 : // IA32 assembly may/will sign-extend 8-bit literals, so we attempt to encode
28 : // in 8 bits only those literals whose value will be unchanged by that
29 : // treatment.
30 E : input_value |= 0x7F;
31 :
32 E : if (input_value == 0xFFFFFFFF || input_value == 0x7F)
33 E : return core::kSize8Bit;
34 :
35 E : return core::kSize32Bit;
36 E : }
37 :
38 : ValueImpl CopyValue(const UntypedReference* ref,
39 E : const core::ValueImpl& value) {
40 : return ValueImpl(value.value(),
41 : value.size(),
42 E : value.reference() ? ref : NULL);
43 E : }
44 :
45 E : size_t ToBytes(core::ValueSize size) {
46 E : switch (size) {
47 E : case core::kSize8Bit: return 1;
48 E : case core::kSize32Bit: return 4;
49 : }
50 i : NOTREACHED();
51 i : return 0;
52 E : }
53 :
54 : // Completes a UntypedReference, converting it to a BasicBlockReference
55 : // using the provided type and size information.
56 : // @param ref_info The type and size information to use.
57 : // @param untyped_ref The untyped reference to be completed.
58 : // @returns the equivalent BasicBlockReference.
59 : BasicBlockReference CompleteUntypedReference(
60 : BlockGraph::ReferenceType type,
61 : size_t size,
62 E : const UntypedReference& untyped_ref) {
63 E : DCHECK(untyped_ref.IsValid());
64 :
65 : if (untyped_ref.referred_type() ==
66 E : BasicBlockReference::REFERRED_TYPE_BLOCK) {
67 E : DCHECK(untyped_ref.block() != NULL);
68 : return BasicBlockReference(type, size, untyped_ref.block(),
69 E : untyped_ref.offset(), untyped_ref.base());
70 : }
71 :
72 : DCHECK_EQ(BasicBlockReference::REFERRED_TYPE_BASIC_BLOCK,
73 E : untyped_ref.referred_type());
74 E : DCHECK(untyped_ref.basic_block() != NULL);
75 E : return BasicBlockReference(type, size, untyped_ref.basic_block());
76 E : }
77 :
78 : } // namespace
79 :
80 E : Value::Value() {
81 E : }
82 :
83 E : Value::Value(uint32 value) : value_(value, ValueSizeFromConstant(value)) {
84 E : }
85 :
86 E : Value::Value(uint32 value, ValueSize size) : value_(value, size) {
87 E : }
88 :
89 : Value::Value(BasicBlock* bb)
90 : : reference_(bb),
91 E : value_(0, core::kSize32Bit, &reference_) {
92 E : }
93 :
94 : Value::Value(Block* block, Offset offset)
95 : : reference_(block, offset, offset),
96 E : value_(0, core::kSize32Bit, &reference_) {
97 E : }
98 :
99 : Value::Value(Block* block, Offset offset, Offset base)
100 : : reference_(block, offset, base),
101 : value_(0, core::kSize32Bit, &reference_) {
102 : }
103 :
104 : Value::Value(uint32 value, ValueSize size, const UntypedReference& ref)
105 E : : reference_(ref), value_(value, size, &reference_) {
106 E : DCHECK(ref.IsValid());
107 E : }
108 :
109 : Value::Value(const Value& other)
110 : : reference_(other.reference()),
111 E : value_(CopyValue(&reference_, other.value_)) {
112 E : }
113 :
114 : Value::Value(const UntypedReference& ref, const ValueImpl& value)
115 E : : reference_(ref), value_(CopyValue(&reference_, value)) {
116 E : }
117 :
118 E : Value::~Value() {
119 : #ifndef NDEBUG
120 E : if (reference_.IsValid()) {
121 E : DCHECK(value_.reference() == &reference_);
122 E : } else {
123 E : DCHECK(value_.reference() == NULL);
124 : }
125 : #endif
126 E : }
127 :
128 E : const Value& Value::operator=(const Value& other) {
129 E : reference_ = other.reference_;
130 E : value_ = CopyValue(&reference_, other.value_);
131 E : return *this;
132 E : }
133 :
134 E : bool Value::operator==(const Value& rhs) const {
135 E : if (reference_.IsValid())
136 i : return reference_ == rhs.reference();
137 E : return value_ == rhs.value_;
138 E : }
139 :
140 E : Operand::Operand(core::Register base) : operand_(base) {
141 E : }
142 :
143 : Operand::Operand(core::Register base, const Displacement& displ)
144 : : reference_(displ.reference()),
145 E : operand_(base, CopyValue(&reference_, displ.value_)) {
146 E : }
147 :
148 : Operand::Operand(const Displacement& displ)
149 : : reference_(displ.reference()),
150 E : operand_(CopyValue(&reference_, displ.value_)) {
151 E : }
152 :
153 : Operand::Operand(core::Register base,
154 : core::Register index,
155 : core::ScaleFactor scale,
156 : const Displacement& displ)
157 : : reference_(displ.reference_),
158 E : operand_(base, index, scale, CopyValue(&reference_, displ.value_)) {
159 E : }
160 :
161 : Operand::Operand(core::Register base,
162 : core::Register index,
163 : core::ScaleFactor scale)
164 E : : operand_(base, index, scale) {
165 E : }
166 :
167 : Operand::Operand(core::Register index,
168 : core::ScaleFactor scale,
169 : const Displacement& displ)
170 : : reference_(displ.reference_),
171 E : operand_(index, scale, CopyValue(&reference_, displ.value_)) {
172 E : }
173 :
174 : Operand::Operand(const Operand& o)
175 : : reference_(o.reference_),
176 : operand_(o.base(), o.index(), o.scale(),
177 E : CopyValue(&reference_, o.operand_.displacement())) {
178 E : }
179 :
180 E : Operand::~Operand() {
181 : #ifndef NDEBUG
182 E : if (reference_.IsValid()) {
183 E : DCHECK(operand_.displacement().reference() == &reference_);
184 E : } else {
185 E : DCHECK(operand_.displacement().reference() == NULL);
186 : }
187 : #endif
188 E : }
189 :
190 E : const Operand& Operand::operator=(const Operand& other) {
191 E : reference_ = other.reference_;
192 : operand_ =
193 : core::OperandImpl(other.base(), other.index(), other.scale(),
194 E : CopyValue(&reference_, other.operand_.displacement()));
195 E : return *this;
196 E : }
197 :
198 : BasicBlockAssembler::BasicBlockSerializer::BasicBlockSerializer(
199 : const Instructions::iterator& where, Instructions* list)
200 E : : where_(where), list_(list), num_ref_infos_(0) {
201 E : DCHECK(list != NULL);
202 E : }
203 :
204 : void BasicBlockAssembler::BasicBlockSerializer::AppendInstruction(
205 : uint32 location, const uint8* bytes, size_t num_bytes,
206 E : const size_t *ref_locations, const void* const* refs, size_t num_refs) {
207 : // The number of reference infos we've been provided must match the number of
208 : // references we have been given.
209 E : DCHECK_EQ(num_ref_infos_, num_refs);
210 :
211 E : Instruction instruction;
212 E : CHECK(Instruction::FromBuffer(bytes, num_bytes, &instruction));
213 E : instruction.set_source_range(source_range_);
214 :
215 E : Instructions::iterator it = list_->insert(where_, instruction);
216 :
217 E : for (size_t i = 0; i < num_refs; ++i) {
218 : const UntypedReference* tref =
219 E : reinterpret_cast<const UntypedReference*>(refs[i]);
220 E : DCHECK(tref != NULL);
221 :
222 : BasicBlockReference bbref = CompleteUntypedReference(
223 E : ref_infos_[i].type, ref_infos_[i].size, *tref);
224 E : DCHECK(bbref.IsValid());
225 E : it->SetReference(ref_locations[i], bbref);
226 E : }
227 :
228 : // Clear the reference info for the next instruction.
229 E : num_ref_infos_ = 0;
230 E : }
231 :
232 : void BasicBlockAssembler::BasicBlockSerializer::PushReferenceInfo(
233 E : BlockGraph::ReferenceType type, core::ValueSize size) {
234 E : DCHECK_GT(2u, num_ref_infos_);
235 E : ref_infos_[num_ref_infos_].type = type;
236 E : ref_infos_[num_ref_infos_].size = ToBytes(size);
237 E : ++num_ref_infos_;
238 E : }
239 :
240 : BasicBlockAssembler::BasicBlockAssembler(const Instructions::iterator& where,
241 : Instructions* list)
242 E : : serializer_(where, list), asm_(0, &serializer_) {
243 E : }
244 :
245 : BasicBlockAssembler::BasicBlockAssembler(uint32 location,
246 : const Instructions::iterator& where,
247 : Instructions* list)
248 E : : serializer_(where, list), asm_(location, &serializer_) {
249 E : }
250 :
251 E : void BasicBlockAssembler::call(const Immediate& dst) {
252 : // In the context of BasicBlockAssembler it only makes sense for calls with
253 : // immediate parameters to be backed by a 32-bit reference.
254 E : PushMandatoryReferenceInfo(BlockGraph::PC_RELATIVE_REF, dst);
255 E : CheckReferenceSize(core::kSize32Bit, dst);
256 E : asm_.call(dst.value_);
257 E : }
258 :
259 E : void BasicBlockAssembler::call(const Operand& dst) {
260 : // If a call is backed by a reference it must be 32-bit.
261 E : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, dst);
262 E : CheckReferenceSize(core::kSize32Bit, dst);
263 E : asm_.call(dst.operand_);
264 E : }
265 :
266 E : void BasicBlockAssembler::jmp(const Immediate& dst) {
267 : // In the context of BasicBlockAssembler it only makes sense for jumps with
268 : // immediate parameters to be backed by a reference.
269 E : PushMandatoryReferenceInfo(BlockGraph::PC_RELATIVE_REF, dst);
270 E : asm_.jmp(dst.value_);
271 E : }
272 :
273 E : void BasicBlockAssembler::jmp(const Operand& dst) {
274 E : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, dst);
275 E : asm_.jmp(dst.operand_);
276 E : }
277 :
278 E : void BasicBlockAssembler::j(ConditionCode code, const Immediate& dst) {
279 : // In the context of BasicBlockAssembler it only makes sense for jumps with
280 : // immediate parameters to be backed by a reference.
281 E : PushMandatoryReferenceInfo(BlockGraph::PC_RELATIVE_REF, dst);
282 E : asm_.j(code, dst.value_);
283 E : }
284 :
285 E : void BasicBlockAssembler::set(ConditionCode code, Register dst) {
286 E : asm_.set(code, dst);
287 E : }
288 :
289 E : void BasicBlockAssembler::pushfd() {
290 E : asm_.pushfd();
291 E : }
292 :
293 E : void BasicBlockAssembler::popfd() {
294 E : asm_.popfd();
295 E : }
296 :
297 E : void BasicBlockAssembler::lahf() {
298 E : asm_.lahf();
299 E : }
300 :
301 E : void BasicBlockAssembler::sahf() {
302 E : asm_.sahf();
303 E : }
304 :
305 E : void BasicBlockAssembler::test_b(Register dst, Register src) {
306 E : asm_.test_b(dst, src);
307 E : }
308 :
309 E : void BasicBlockAssembler::test_b(Register dst, const Immediate& src) {
310 E : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
311 E : asm_.test_b(dst, src.value_);
312 E : }
313 :
314 E : void BasicBlockAssembler::test(Register dst, Register src) {
315 E : asm_.test(dst, src);
316 E : }
317 :
318 : void BasicBlockAssembler::test(Register dst, const Operand& src) {
319 : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
320 : asm_.test(dst, src.operand_);
321 : }
322 :
323 : void BasicBlockAssembler::test(const Operand& dst, Register src) {
324 : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, dst);
325 : asm_.test(dst.operand_, src);
326 : }
327 :
328 E : void BasicBlockAssembler::test(Register dst, const Immediate& src) {
329 E : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
330 E : asm_.test(dst, src.value_);
331 E : }
332 :
333 E : void BasicBlockAssembler::test(const Operand& dst, const Immediate& src) {
334 E : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, dst);
335 E : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
336 E : asm_.test(dst.operand_, src.value_);
337 E : }
338 :
339 E : void BasicBlockAssembler::cmp_b(Register dst, Register src) {
340 E : asm_.cmp_b(dst, src);
341 E : }
342 :
343 E : void BasicBlockAssembler::cmp_b(Register dst, const Immediate& src) {
344 E : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
345 E : asm_.cmp_b(dst, src.value_);
346 E : }
347 :
348 E : void BasicBlockAssembler::cmp(Register dst, Register src) {
349 E : asm_.cmp(dst, src);
350 E : }
351 :
352 : void BasicBlockAssembler::cmp(Register dst, const Operand& src) {
353 : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
354 : asm_.cmp(dst, src.operand_);
355 : }
356 :
357 : void BasicBlockAssembler::cmp(const Operand& dst, Register src) {
358 : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, dst);
359 : asm_.cmp(dst.operand_, src);
360 : }
361 :
362 E : void BasicBlockAssembler::cmp(Register dst, const Immediate& src) {
363 E : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
364 E : asm_.cmp(dst, src.value_);
365 E : }
366 :
367 E : void BasicBlockAssembler::cmp(const Operand& dst, const Immediate& src) {
368 E : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, dst);
369 E : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
370 E : asm_.cmp(dst.operand_, src.value_);
371 E : }
372 :
373 E : void BasicBlockAssembler::add_b(Register dst, Register src) {
374 E : asm_.add_b(dst, src);
375 E : }
376 :
377 E : void BasicBlockAssembler::add_b(Register dst, const Immediate& src) {
378 E : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
379 E : asm_.add_b(dst, src.value_);
380 E : }
381 :
382 E : void BasicBlockAssembler::add(Register dst, Register src) {
383 E : asm_.add(dst, src);
384 E : }
385 :
386 : void BasicBlockAssembler::add(Register dst, const Operand& src) {
387 : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
388 : asm_.add(dst, src.operand_);
389 : }
390 :
391 : void BasicBlockAssembler::add(const Operand& dst, Register src) {
392 : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, dst);
393 : asm_.add(dst.operand_, src);
394 : }
395 :
396 E : void BasicBlockAssembler::add(Register dst, const Immediate& src) {
397 E : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
398 E : asm_.add(dst, src.value_);
399 E : }
400 :
401 E : void BasicBlockAssembler::add(const Operand& dst, const Immediate& src) {
402 E : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, dst);
403 E : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
404 E : asm_.add(dst.operand_, src.value_);
405 E : }
406 :
407 E : void BasicBlockAssembler::sub_b(Register dst, Register src) {
408 E : asm_.sub_b(dst, src);
409 E : }
410 :
411 E : void BasicBlockAssembler::sub_b(Register dst, const Immediate& src) {
412 E : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
413 E : asm_.sub_b(dst, src.value_);
414 E : }
415 :
416 E : void BasicBlockAssembler::sub(Register dst, Register src) {
417 E : asm_.sub(dst, src);
418 E : }
419 :
420 : void BasicBlockAssembler::sub(Register dst, const Operand& src) {
421 : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
422 : asm_.sub(dst, src.operand_);
423 : }
424 :
425 : void BasicBlockAssembler::sub(const Operand& dst, Register src) {
426 : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, dst);
427 : asm_.sub(dst.operand_, src);
428 : }
429 :
430 E : void BasicBlockAssembler::sub(Register dst, const Immediate& src) {
431 E : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
432 E : asm_.sub(dst, src.value_);
433 E : }
434 :
435 E : void BasicBlockAssembler::sub(const Operand& dst, const Immediate& src) {
436 E : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, dst);
437 E : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
438 E : asm_.sub(dst.operand_, src.value_);
439 E : }
440 :
441 E : void BasicBlockAssembler::shl(Register dst, const Immediate& src) {
442 E : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
443 E : asm_.shl(dst, src.value_);
444 E : }
445 :
446 E : void BasicBlockAssembler::shr(Register dst, const Immediate& src) {
447 E : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
448 E : asm_.shr(dst, src.value_);
449 E : }
450 :
451 E : void BasicBlockAssembler::mov_b(const Operand& dst, const Immediate& src) {
452 E : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, dst);
453 E : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
454 E : CheckReferenceSize(core::kSize32Bit, dst);
455 E : CheckReferenceSize(core::kSize32Bit, src);
456 E : asm_.mov_b(dst.operand_, src.value_);
457 E : }
458 :
459 E : void BasicBlockAssembler::movzx_b(Register dst, const Operand& src) {
460 E : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
461 E : CheckReferenceSize(core::kSize32Bit, src);
462 E : asm_.movzx_b(dst, src.operand_);
463 E : }
464 :
465 E : void BasicBlockAssembler::mov(Register dst, Register src) {
466 E : asm_.mov(dst, src);
467 E : }
468 :
469 E : void BasicBlockAssembler::mov(Register dst, const Operand& src) {
470 E : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
471 E : CheckReferenceSize(core::kSize32Bit, src);
472 E : asm_.mov(dst, src.operand_);
473 E : }
474 :
475 E : void BasicBlockAssembler::mov(const Operand& dst, Register src) {
476 E : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, dst);
477 E : CheckReferenceSize(core::kSize32Bit, dst);
478 E : asm_.mov(dst.operand_, src);
479 E : }
480 :
481 E : void BasicBlockAssembler::mov(Register dst, const Immediate& src) {
482 E : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
483 E : CheckReferenceSize(core::kSize32Bit, src);
484 E : asm_.mov(dst, src.value_);
485 E : }
486 :
487 E : void BasicBlockAssembler::mov(const Operand& dst, const Immediate& src) {
488 E : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, dst);
489 E : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
490 E : CheckReferenceSize(core::kSize32Bit, dst);
491 E : CheckReferenceSize(core::kSize32Bit, src);
492 E : asm_.mov(dst.operand_, src.value_);
493 E : }
494 :
495 E : void BasicBlockAssembler::mov_fs(Register dst, const Operand& src) {
496 E : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
497 E : CheckReferenceSize(core::kSize32Bit, src);
498 E : asm_.mov_fs(dst, src.operand_);
499 E : }
500 :
501 E : void BasicBlockAssembler::mov_fs(const Operand& dst, Register src) {
502 E : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, dst);
503 E : CheckReferenceSize(core::kSize32Bit, dst);
504 E : asm_.mov_fs(dst.operand_, src);
505 E : }
506 :
507 E : void BasicBlockAssembler::lea(Register dst, const Operand& src) {
508 E : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
509 E : CheckReferenceSize(core::kSize32Bit, src);
510 E : asm_.lea(dst, src.operand_);
511 E : }
512 :
513 E : void BasicBlockAssembler::push(Register src) {
514 E : asm_.push(src);
515 E : }
516 :
517 E : void BasicBlockAssembler::push(const Immediate& src) {
518 E : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
519 E : CheckReferenceSize(core::kSize32Bit, src);
520 E : asm_.push(src.value_);
521 E : }
522 :
523 E : void BasicBlockAssembler::push(const Operand& src) {
524 E : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, src);
525 E : CheckReferenceSize(core::kSize32Bit, src);
526 E : asm_.push(src.operand_);
527 E : }
528 :
529 E : void BasicBlockAssembler::pop(Register dst) {
530 E : asm_.pop(dst);
531 E : }
532 :
533 E : void BasicBlockAssembler::pop(const Operand& dst) {
534 E : PushOptionalReferenceInfo(BlockGraph::ABSOLUTE_REF, dst);
535 E : CheckReferenceSize(core::kSize32Bit, dst);
536 E : asm_.pop(dst.operand_);
537 E : }
538 :
539 E : void BasicBlockAssembler::ret() {
540 E : asm_.ret();
541 E : }
542 :
543 E : void BasicBlockAssembler::ret(uint16 n) {
544 E : asm_.ret(n);
545 E : }
546 :
547 : void BasicBlockAssembler::PushMandatoryReferenceInfo(
548 E : ReferenceType type, const Immediate& imm) {
549 E : DCHECK(imm.value_.reference() != NULL);
550 E : serializer_.PushReferenceInfo(type, imm.value_.size());
551 E : }
552 :
553 : void BasicBlockAssembler::PushOptionalReferenceInfo(
554 E : ReferenceType type, const Immediate& imm) {
555 E : if (imm.value_.reference() == NULL)
556 E : return;
557 E : serializer_.PushReferenceInfo(type, imm.value_.size());
558 E : }
559 :
560 : void BasicBlockAssembler::PushOptionalReferenceInfo(
561 E : ReferenceType type, const Operand& op) {
562 E : if (op.operand_.displacement().reference() == NULL)
563 E : return;
564 E : serializer_.PushReferenceInfo(type, op.operand_.displacement().size());
565 E : }
566 :
567 : void BasicBlockAssembler::CheckReferenceSize(
568 E : core::ValueSize size, const Immediate& imm) const {
569 E : DCHECK(imm.value_.reference() == NULL || imm.value_.size() == size);
570 E : }
571 :
572 : void BasicBlockAssembler::CheckReferenceSize(
573 E : core::ValueSize size, const Operand& op) const {
574 : DCHECK(op.operand_.displacement().reference() == NULL ||
575 E : op.operand_.displacement().size() == size);
576 E : }
577 :
578 : } // namespace block_graph
|