Chromium Code Reviews

Side by Side Diff: src/assembler_ia32.h

Issue 476323004: Start adding an integrated assembler. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: simplify Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
OLDNEW
(Empty)
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file.
4 //
5 // Modified by the Subzero authors.
6 //
7 //===- subzero/src/assembler_ia32.h - Assembler for x86-32 ----------------===//
8 //
9 // The Subzero Code Generator
10 //
11 // This file is distributed under the University of Illinois Open Source
12 // License. See LICENSE.TXT for details.
13 //
14 //===----------------------------------------------------------------------===//
15 //
16 // This file implements the Assembler class for x86-32.
17 //
18 //===----------------------------------------------------------------------===//
19
20 #ifndef SUBZERO_SRC_ASSEMBLER_IA32_H_
21 #define SUBZERO_SRC_ASSEMBLER_IA32_H_
22
23 #include "IceDefs.h"
24 #include "IceUtils.h"
25
26 // Rename to be Ice*...?
27 #include "assembler.h"
28 #include "assembler_constants_ia32.h"
29 // Hmm, assembler_ia32.h includes IceInstX8632.h, but IceInstX8632.cpp includes
30 // assembler_ia32.h. Or we can move the BrCond out to, or some other
31 // common group of enums assembler_constants_ia32.h.
32
33 namespace Ice {
34
35 class Assembler;
36 class ConstantRelocatable;
37
38 namespace x86 {
39
40 class Immediate {
41 public:
42 explicit Immediate(int32_t value) : value_(value) {}
43
44 Immediate(const Immediate &other) : value_(other.value_) {}
45
46 int32_t value() const { return value_; }
47
48 bool is_int8() const { return Utils::IsInt(8, value_); }
49 bool is_uint8() const { return Utils::IsUint(8, value_); }
50 bool is_uint16() const { return Utils::IsUint(16, value_); }
51
52 private:
53 const int32_t value_;
54
55 // TODO(5411081): Add DISALLOW_COPY_AND_ASSIGN(Immediate) once the mac
56 // build issue is resolved.
57 // And remove the unnecessary copy constructor.
58 };
59
60 class Operand {
61 public:
62 uint8_t mod() const { return (encoding_at(0) >> 6) & 3; }
63
64 Register rm() const { return static_cast<Register>(encoding_at(0) & 7); }
65
66 ScaleFactor scale() const {
67 return static_cast<ScaleFactor>((encoding_at(1) >> 6) & 3);
68 }
69
70 Register index() const {
71 return static_cast<Register>((encoding_at(1) >> 3) & 7);
72 }
73
74 Register base() const { return static_cast<Register>(encoding_at(1) & 7); }
75
76 int8_t disp8() const {
77 assert(length_ >= 2);
78 return static_cast<int8_t>(encoding_[length_ - 1]);
79 }
80
81 int32_t disp32() const {
82 assert(length_ >= 5);
83 return bit_copy<int32_t>(encoding_[length_ - 4]);
84 }
85
86 Operand(const Operand &other) : length_(other.length_) {
87 memmove(&encoding_[0], &other.encoding_[0], other.length_);
88 }
89
90 Operand &operator=(const Operand &other) {
91 length_ = other.length_;
92 memmove(&encoding_[0], &other.encoding_[0], other.length_);
93 return *this;
94 }
95
96 bool Equals(const Operand &other) const {
97 if (length_ != other.length_)
98 return false;
99 for (uint8_t i = 0; i < length_; i++) {
100 if (encoding_[i] != other.encoding_[i])
101 return false;
102 }
103 return true;
104 }
105
106 protected:
107 Operand() : length_(0) {} // Needed by subclass Address.
108
109 void SetModRM(int mod, Register rm) {
110 assert((mod & ~3) == 0);
111 encoding_[0] = (mod << 6) | rm;
112 length_ = 1;
113 }
114
115 void SetSIB(ScaleFactor scale, Register index, Register base) {
116 assert(length_ == 1);
117 assert((scale & ~3) == 0);
118 encoding_[1] = (scale << 6) | (index << 3) | base;
119 length_ = 2;
120 }
121
122 void SetDisp8(int8_t disp) {
123 assert(length_ == 1 || length_ == 2);
124 encoding_[length_++] = static_cast<uint8_t>(disp);
125 }
126
127 void SetDisp32(int32_t disp) {
128 assert(length_ == 1 || length_ == 2);
129 intptr_t disp_size = sizeof(disp);
130 memmove(&encoding_[length_], &disp, disp_size);
131 length_ += disp_size;
132 }
133
134 private:
135 uint8_t length_;
136 uint8_t encoding_[6];
137 uint8_t padding_;
138
139 explicit Operand(Register reg) { SetModRM(3, reg); }
140
141 // Get the operand encoding byte at the given index.
142 uint8_t encoding_at(intptr_t index) const {
143 assert(index >= 0 && index < length_);
144 return encoding_[index];
145 }
146
147 // Returns whether or not this operand is really the given register in
148 // disguise. Used from the assembler to generate better encodings.
149 bool IsRegister(Register reg) const {
150 return ((encoding_[0] & 0xF8) == 0xC0) // Addressing mode is register only.
151 && ((encoding_[0] & 0x07) == reg); // Register codes match.
152 }
153
154 friend class AssemblerX86;
155 };
156
157 class Address : public Operand {
158 public:
159 Address(Register base, int32_t disp) {
160 if (disp == 0 && base != EBP) {
161 SetModRM(0, base);
162 if (base == ESP)
163 SetSIB(TIMES_1, ESP, base);
164 } else if (Utils::IsInt(8, disp)) {
165 SetModRM(1, base);
166 if (base == ESP)
167 SetSIB(TIMES_1, ESP, base);
168 SetDisp8(disp);
169 } else {
170 SetModRM(2, base);
171 if (base == ESP)
172 SetSIB(TIMES_1, ESP, base);
173 SetDisp32(disp);
174 }
175 }
176
177 Address(Register index, ScaleFactor scale, int32_t disp) {
178 assert(index != ESP); // Illegal addressing mode.
179 SetModRM(0, ESP);
180 SetSIB(scale, index, EBP);
181 SetDisp32(disp);
182 }
183
184 Address(Register base, Register index, ScaleFactor scale, int32_t disp) {
185 assert(index != ESP); // Illegal addressing mode.
186 if (disp == 0 && base != EBP) {
187 SetModRM(0, ESP);
188 SetSIB(scale, index, base);
189 } else if (Utils::IsInt(8, disp)) {
190 SetModRM(1, ESP);
191 SetSIB(scale, index, base);
192 SetDisp8(disp);
193 } else {
194 SetModRM(2, ESP);
195 SetSIB(scale, index, base);
196 SetDisp32(disp);
197 }
198 }
199
200 Address(const Address &other) : Operand(other) {}
201
202 Address &operator=(const Address &other) {
203 Operand::operator=(other);
204 return *this;
205 }
206
207 static Address Absolute(const uintptr_t addr) {
208 Address result;
209 result.SetModRM(0, EBP);
210 result.SetDisp32(addr);
211 return result;
212 }
213
214 private:
215 Address() {} // Needed by Address::Absolute.
216 };
217
218 // Hmm... reuse the Ice Labels?
219 class Label {
220 public:
221 Label() : position_(0), unresolved_(0) {
222 #ifdef DEBUG
223 for (int i = 0; i < kMaxUnresolvedBranches; i++) {
224 unresolved_near_positions_[i] = -1;
225 }
226 #endif // DEBUG
227 }
228
229 ~Label() {
230 // Assert if label is being destroyed with unresolved branches pending.
231 assert(!IsLinked());
232 assert(!HasNear());
233 }
234
235 // Returns the position for bound labels. Cannot be used for unused or linked
236 // labels.
237 // TODO(jvoung): what's the difference between Position and LinkPosition()
238 // and why offset by kWordSize?
239 intptr_t Position() const {
240 assert(IsBound());
241 return -position_ - kWordSize;
242 }
243
244 intptr_t LinkPosition() const {
245 assert(IsLinked());
246 return position_ - kWordSize;
247 }
248
249 intptr_t NearPosition() {
250 assert(HasNear());
251 return unresolved_near_positions_[--unresolved_];
252 }
253
254 bool IsBound() const { return position_ < 0; }
255 bool IsUnused() const { return (position_ == 0) && (unresolved_ == 0); }
256 bool IsLinked() const { return position_ > 0; }
257 bool HasNear() const { return unresolved_ != 0; }
258
259 private:
260 void BindTo(intptr_t position) {
261 assert(!IsBound());
262 assert(!HasNear());
263 position_ = -position - kWordSize;
264 assert(IsBound());
265 }
266
267 void LinkTo(intptr_t position) {
268 assert(!IsBound());
269 position_ = position + kWordSize;
270 assert(IsLinked());
271 }
272
273 void NearLinkTo(intptr_t position) {
274 assert(!IsBound());
275 assert(unresolved_ < kMaxUnresolvedBranches);
276 unresolved_near_positions_[unresolved_++] = position;
277 }
278
279 static const int kMaxUnresolvedBranches = 20;
280
281 intptr_t position_;
282 intptr_t unresolved_;
283 intptr_t unresolved_near_positions_[kMaxUnresolvedBranches];
284
285 friend class AssemblerX86;
286 Label(const Label &) LLVM_DELETED_FUNCTION;
287 Label &operator=(const Label &) LLVM_DELETED_FUNCTION;
288 };
289
290 class AssemblerX86 : public Assembler {
291 public:
292 explicit AssemblerX86(bool use_far_branches = false) : buffer_(*this) {
293 // This mode is only needed and implemented for MIPS and ARM.
294 assert(!use_far_branches);
295 }
296 ~AssemblerX86() {}
297
298 static const bool kNearJump = true;
299 static const bool kFarJump = false;
300
301 typedef void (AssemblerX86::*EmitRegByteR)(Register, ByteRegister);
302 typedef void (AssemblerX86::*EmitRegReg)(Register, Register);
303 typedef void (AssemblerX86::*EmitRegAddr)(Register, const Address &);
304 typedef void (AssemblerX86::*EmitXmmXmm)(XmmRegister, XmmRegister);
305 typedef void (AssemblerX86::*EmitXmmAddr)(XmmRegister, const Address &);
306 typedef void (AssemblerX86::*EmitAddrXmm)(const Address &, XmmRegister);
307
308 /*
309 * Emit Machine Instructions.
310 */
311 void call(Register reg);
312 void call(const Address &address);
313 void call(Label *label);
314 void call(const ConstantRelocatable *label);
315
316 static const intptr_t kCallExternalLabelSize = 5;
317
318 void pushl(Register reg);
319 void pushl(const Address &address);
320 void pushl(const Immediate &imm);
321
322 void popl(Register reg);
323 void popl(const Address &address);
324
325 void pushal();
326 void popal();
327
328 void setcc(Condition condition, ByteRegister dst);
329
330 void movl(Register dst, const Immediate &src);
331 void movl(Register dst, Register src);
332
333 void movl(Register dst, const Address &src);
334 void movl(const Address &dst, Register src);
335 void movl(const Address &dst, const Immediate &imm);
336
337 void movzxb(Register dst, ByteRegister src);
338 void movzxb(Register dst, const Address &src);
339 void movsxb(Register dst, ByteRegister src);
340 void movsxb(Register dst, const Address &src);
341
342 void movb(ByteRegister dst, const Address &src);
343 void movb(const Address &dst, ByteRegister src);
344 void movb(const Address &dst, const Immediate &imm);
345
346 void movzxw(Register dst, Register src);
347 void movzxw(Register dst, const Address &src);
348 void movsxw(Register dst, Register src);
349 void movsxw(Register dst, const Address &src);
350 void movw(Register dst, const Address &src);
351 void movw(const Address &dst, Register src);
352
353 void leal(Register dst, const Address &src);
354
355 void cmov(Condition cond, Register dst, Register src);
356
357 void rep_movsb();
358
359 void movss(XmmRegister dst, const Address &src);
360 void movss(const Address &dst, XmmRegister src);
361 void movss(XmmRegister dst, XmmRegister src);
362
363 void movd(XmmRegister dst, Register src);
364 void movd(Register dst, XmmRegister src);
365
366 void movq(const Address &dst, XmmRegister src);
367 void movq(XmmRegister dst, const Address &src);
368
369 void addss(XmmRegister dst, XmmRegister src);
370 void addss(XmmRegister dst, const Address &src);
371 void subss(XmmRegister dst, XmmRegister src);
372 void subss(XmmRegister dst, const Address &src);
373 void mulss(XmmRegister dst, XmmRegister src);
374 void mulss(XmmRegister dst, const Address &src);
375 void divss(XmmRegister dst, XmmRegister src);
376 void divss(XmmRegister dst, const Address &src);
377
378 void movsd(XmmRegister dst, const Address &src);
379 void movsd(const Address &dst, XmmRegister src);
380 void movsd(XmmRegister dst, XmmRegister src);
381
382 void movaps(XmmRegister dst, XmmRegister src);
383
384 void movups(XmmRegister dst, const Address &src);
385 void movups(const Address &dst, XmmRegister src);
386
387 void addsd(XmmRegister dst, XmmRegister src);
388 void addsd(XmmRegister dst, const Address &src);
389 void subsd(XmmRegister dst, XmmRegister src);
390 void subsd(XmmRegister dst, const Address &src);
391 void mulsd(XmmRegister dst, XmmRegister src);
392 void mulsd(XmmRegister dst, const Address &src);
393 void divsd(XmmRegister dst, XmmRegister src);
394 void divsd(XmmRegister dst, const Address &src);
395
396 void addpl(XmmRegister dst, XmmRegister src);
397 void subpl(XmmRegister dst, XmmRegister src);
398 void addps(XmmRegister dst, XmmRegister src);
399 void addps(XmmRegister dst, const Address &src);
400 void subps(XmmRegister dst, XmmRegister src);
401 void subps(XmmRegister dst, const Address &src);
402 void divps(XmmRegister dst, XmmRegister src);
403 void divps(XmmRegister dst, const Address &src);
404 void mulps(XmmRegister dst, XmmRegister src);
405 void mulps(XmmRegister dst, const Address &src);
406 void minps(XmmRegister dst, XmmRegister src);
407 void maxps(XmmRegister dst, XmmRegister src);
408 void andps(XmmRegister dst, XmmRegister src);
409 void andps(XmmRegister dst, const Address &src);
410 void orps(XmmRegister dst, XmmRegister src);
411 void notps(XmmRegister dst);
412 void negateps(XmmRegister dst);
413 void absps(XmmRegister dst);
414 void zerowps(XmmRegister dst);
415
416 // TODO(jvoung): Use the enum type instead of uint8_t.
417 void cmpps(XmmRegister dst, XmmRegister src, uint8_t CmpCondition);
418 void cmpps(XmmRegister dst, const Address &src, uint8_t CmpCondition);
419
420 void sqrtps(XmmRegister dst);
421 void rsqrtps(XmmRegister dst);
422 void reciprocalps(XmmRegister dst);
423 void movhlps(XmmRegister dst, XmmRegister src);
424 void movlhps(XmmRegister dst, XmmRegister src);
425 void unpcklps(XmmRegister dst, XmmRegister src);
426 void unpckhps(XmmRegister dst, XmmRegister src);
427 void unpcklpd(XmmRegister dst, XmmRegister src);
428 void unpckhpd(XmmRegister dst, XmmRegister src);
429
430 void set1ps(XmmRegister dst, Register tmp, const Immediate &imm);
431 void shufps(XmmRegister dst, XmmRegister src, const Immediate &mask);
432
433 void addpd(XmmRegister dst, XmmRegister src);
434 void negatepd(XmmRegister dst);
435 void subpd(XmmRegister dst, XmmRegister src);
436 void mulpd(XmmRegister dst, XmmRegister src);
437 void divpd(XmmRegister dst, XmmRegister src);
438 void abspd(XmmRegister dst);
439 void minpd(XmmRegister dst, XmmRegister src);
440 void maxpd(XmmRegister dst, XmmRegister src);
441 void sqrtpd(XmmRegister dst);
442 void cvtps2pd(XmmRegister dst, XmmRegister src);
443 void cvtpd2ps(XmmRegister dst, XmmRegister src);
444 void shufpd(XmmRegister dst, XmmRegister src, const Immediate &mask);
445
446 void cvtsi2ss(XmmRegister dst, Register src);
447 void cvtsi2sd(XmmRegister dst, Register src);
448
449 void cvtss2si(Register dst, XmmRegister src);
450 void cvtss2sd(XmmRegister dst, XmmRegister src);
451
452 void cvtsd2si(Register dst, XmmRegister src);
453 void cvtsd2ss(XmmRegister dst, XmmRegister src);
454
455 void cvttss2si(Register dst, XmmRegister src);
456 void cvttsd2si(Register dst, XmmRegister src);
457
458 void cvtdq2pd(XmmRegister dst, XmmRegister src);
459
460 void comiss(XmmRegister a, XmmRegister b);
461 void comisd(XmmRegister a, XmmRegister b);
462
463 void movmskpd(Register dst, XmmRegister src);
464 void movmskps(Register dst, XmmRegister src);
465
466 void sqrtsd(XmmRegister dst, const Address &src);
467 void sqrtsd(XmmRegister dst, XmmRegister src);
468 void sqrtss(XmmRegister dst, const Address &src);
469 void sqrtss(XmmRegister dst, XmmRegister src);
470
471 void xorpd(XmmRegister dst, const Address &src);
472 void xorpd(XmmRegister dst, XmmRegister src);
473 void xorps(XmmRegister dst, const Address &src);
474 void xorps(XmmRegister dst, XmmRegister src);
475
476 void andpd(XmmRegister dst, const Address &src);
477 void andpd(XmmRegister dst, XmmRegister src);
478
479 void orpd(XmmRegister dst, XmmRegister src);
480
481 void pextrd(Register dst, XmmRegister src, const Immediate &imm);
482 void pmovsxdq(XmmRegister dst, XmmRegister src);
483 void pcmpeqq(XmmRegister dst, XmmRegister src);
484
485 void pxor(XmmRegister dst, XmmRegister src);
486
487 enum RoundingMode {
488 kRoundToNearest = 0x0,
489 kRoundDown = 0x1,
490 kRoundUp = 0x2,
491 kRoundToZero = 0x3
492 };
493 void roundsd(XmmRegister dst, XmmRegister src, RoundingMode mode);
494
495 void flds(const Address &src);
496 void fstps(const Address &dst);
497
498 void fldl(const Address &src);
499 void fstpl(const Address &dst);
500
501 void fnstcw(const Address &dst);
502 void fldcw(const Address &src);
503
504 void fistpl(const Address &dst);
505 void fistps(const Address &dst);
506 void fildl(const Address &src);
507 void filds(const Address &src);
508
509 void fincstp();
510
511 void xchgl(Register dst, Register src);
512
513 void cmpl(Register reg, const Immediate &imm);
514 void cmpl(Register reg0, Register reg1);
515 void cmpl(Register reg, const Address &address);
516
517 void cmpl(const Address &address, Register reg);
518 void cmpl(const Address &address, const Immediate &imm);
519 void cmpb(const Address &address, const Immediate &imm);
520
521 void testl(Register reg1, Register reg2);
522 void testl(Register reg, const Immediate &imm);
523
524 void andl(Register dst, const Immediate &imm);
525 void andl(Register dst, Register src);
526 void andl(Register dst, const Address &address);
527
528 void orl(Register dst, const Immediate &imm);
529 void orl(Register dst, Register src);
530 void orl(Register dst, const Address &address);
531
532 void xorl(Register dst, const Immediate &imm);
533 void xorl(Register dst, Register src);
534 void xorl(Register dst, const Address &address);
535
536 void addl(Register dst, Register src);
537 void addl(Register reg, const Immediate &imm);
538 void addl(Register reg, const Address &address);
539
540 void addl(const Address &address, Register reg);
541 void addl(const Address &address, const Immediate &imm);
542
543 void adcl(Register dst, Register src);
544 void adcl(Register reg, const Immediate &imm);
545 void adcl(Register dst, const Address &address);
546 void adcl(const Address &dst, Register src);
547
548 void subl(Register dst, Register src);
549 void subl(Register reg, const Immediate &imm);
550 void subl(Register reg, const Address &address);
551 void subl(const Address &address, Register reg);
552
553 void cbw();
554 void cwd();
555 void cdq();
556
557 void idivl(Register reg);
558
559 void imull(Register dst, Register src);
560 void imull(Register reg, const Immediate &imm);
561 void imull(Register reg, const Address &address);
562
563 void imull(Register reg);
564 void imull(const Address &address);
565
566 void mull(Register reg);
567 void mull(const Address &address);
568
569 void sbbl(Register dst, Register src);
570 void sbbl(Register reg, const Immediate &imm);
571 void sbbl(Register reg, const Address &address);
572 void sbbl(const Address &address, Register reg);
573
574 void incl(Register reg);
575 void incl(const Address &address);
576
577 void decl(Register reg);
578 void decl(const Address &address);
579
580 void shll(Register reg, const Immediate &imm);
581 void shll(Register operand, Register shifter);
582 void shll(const Address &operand, Register shifter);
583 void shrl(Register reg, const Immediate &imm);
584 void shrl(Register operand, Register shifter);
585 void sarl(Register reg, const Immediate &imm);
586 void sarl(Register operand, Register shifter);
587 void sarl(const Address &address, Register shifter);
588 void shld(Register dst, Register src);
589 void shld(Register dst, Register src, const Immediate &imm);
590 void shld(const Address &operand, Register src);
591 void shrd(Register dst, Register src);
592 void shrd(Register dst, Register src, const Immediate &imm);
593 void shrd(const Address &dst, Register src);
594
595 void negl(Register reg);
596 void notl(Register reg);
597
598 void bsrl(Register dst, Register src);
599
600 void bt(Register base, Register offset);
601
602 void enter(const Immediate &imm);
603 void leave();
604
605 void ret();
606 void ret(const Immediate &imm);
607
608 // 'size' indicates size in bytes and must be in the range 1..8.
609 void nop(int size = 1);
610 void int3();
611 // TODO(jvoung): should Subzero just use hlt instead of ud2?
612 void hlt();
613
614 void j(Condition condition, Label *label, bool near = kFarJump);
615 void j(Condition condition, const ConstantRelocatable *label);
616
617 void jmp(Register reg);
618 void jmp(Label *label, bool near = kFarJump);
619 void jmp(const ConstantRelocatable *label);
620
621 void lock();
622 void cmpxchgl(const Address &address, Register reg);
623
624 // TODO(jvoung): probably don't need this.
625 void cpuid();
626
627 /*
628 * Macros for High-level operations and implemented on all architectures.
629 * TODO(jvoung): Get rid of these?
630 * They are a bit smarter about checking the immediate size though.
631 */
632
633 void AddImmediate(Register reg, const Immediate &imm);
634 void SubImmediate(Register reg, const Immediate &imm);
635
636 void DoubleNegate(XmmRegister d);
637 void FloatNegate(XmmRegister f);
638
639 void DoubleAbs(XmmRegister reg);
640
641 void LockCmpxchgl(const Address &address, Register reg) {
642 lock();
643 cmpxchgl(address, reg);
644 }
645
646 intptr_t PreferredLoopAlignment() { return 16; }
647 void Align(intptr_t alignment, intptr_t offset);
648 void Bind(Label *label);
649
650 intptr_t CodeSize() const { return buffer_.Size(); }
651
652 void FinalizeInstructions(const MemoryRegion &region) {
653 buffer_.FinalizeInstructions(region);
654 }
655
656 // Debugging and bringup support.
657 static void InitializeMemoryWithBreakpoints(uintptr_t data, intptr_t length);
658
659 // Expose the buffer, for bringup...
660 intptr_t GetPosition() const { return buffer_.GetPosition(); }
661 uint8_t LoadBuffer(intptr_t position) const {
662 return buffer_.Load<uint8_t>(position);
663 }
664
665 private:
666 inline void EmitUint8(uint8_t value);
667 inline void EmitInt32(int32_t value);
668 inline void EmitRegisterOperand(int rm, int reg);
669 inline void EmitXmmRegisterOperand(int rm, XmmRegister reg);
670 inline void EmitFixup(AssemblerFixup *fixup);
671 inline void EmitOperandSizeOverride();
672
673 void EmitOperand(int rm, const Operand &operand);
674 void EmitImmediate(const Immediate &imm);
675 void EmitComplex(int rm, const Operand &operand, const Immediate &immediate);
676 void EmitLabel(Label *label, intptr_t instruction_size);
677 void EmitLabelLink(Label *label);
678 void EmitNearLabelLink(Label *label);
679
680 void EmitGenericShift(int rm, Register reg, const Immediate &imm);
681 void EmitGenericShift(int rm, const Operand &operand, Register shifter);
682
683 AssemblerBuffer buffer_;
684
685 // DISALLOW_ALLOCATION(); // disables operator new.
686 AssemblerX86(const AssemblerX86 &) LLVM_DELETED_FUNCTION;
687 AssemblerX86 &operator=(const AssemblerX86 &) LLVM_DELETED_FUNCTION;
688 };
689
690 inline void AssemblerX86::EmitUint8(uint8_t value) {
691 buffer_.Emit<uint8_t>(value);
692 }
693
694 inline void AssemblerX86::EmitInt32(int32_t value) {
695 buffer_.Emit<int32_t>(value);
696 }
697
698 inline void AssemblerX86::EmitRegisterOperand(int rm, int reg) {
699 assert(rm >= 0 && rm < 8);
700 buffer_.Emit<uint8_t>(0xC0 + (rm << 3) + reg);
701 }
702
703 inline void AssemblerX86::EmitXmmRegisterOperand(int rm, XmmRegister reg) {
704 EmitRegisterOperand(rm, static_cast<Register>(reg));
705 }
706
707 inline void AssemblerX86::EmitFixup(AssemblerFixup *fixup) {
708 buffer_.EmitFixup(fixup);
709 }
710
711 inline void AssemblerX86::EmitOperandSizeOverride() { EmitUint8(0x66); }
712
713 } // end of namespace x86
714 } // end of namespace Ice
715
716 #endif // SUBZERO_SRC_ASSEMBLER_IA32_H_
OLDNEW

Powered by Google App Engine