Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(935)

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: lit test to check encodings, swap complexi8 Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
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 "IceTypes.h"
25 #include "IceUtils.h"
26
27 // Rename to be Ice*...?
28 #include "assembler.h"
29 #include "assembler_constants_ia32.h"
30 // Hmm, assembler_ia32.h includes IceInstX8632.h, but IceInstX8632.cpp includes
31 // assembler_ia32.h. Or we can move the BrCond out to, or some other
32 // common group of enums assembler_constants_ia32.h.
33
34 namespace Ice {
35
36 class Assembler;
37 class ConstantRelocatable;
38
39 namespace x86 {
40
41 class Immediate {
42 public:
43 explicit Immediate(int32_t value) : value_(value) {}
44
45 Immediate(const Immediate &other) : value_(other.value_) {}
46
47 int32_t value() const { return value_; }
48
49 bool is_int8() const { return Utils::IsInt(8, value_); }
50 bool is_uint8() const { return Utils::IsUint(8, value_); }
51 bool is_uint16() const { return Utils::IsUint(16, value_); }
52
53 private:
54 const int32_t value_;
55
56 // TODO(5411081): Add DISALLOW_COPY_AND_ASSIGN(Immediate) once the mac
57 // build issue is resolved.
58 // And remove the unnecessary copy constructor.
59 };
60
61 class Operand {
62 public:
63 uint8_t mod() const { return (encoding_at(0) >> 6) & 3; }
64
65 Register rm() const { return static_cast<Register>(encoding_at(0) & 7); }
66
67 ScaleFactor scale() const {
68 return static_cast<ScaleFactor>((encoding_at(1) >> 6) & 3);
69 }
70
71 Register index() const {
72 return static_cast<Register>((encoding_at(1) >> 3) & 7);
73 }
74
75 Register base() const { return static_cast<Register>(encoding_at(1) & 7); }
76
77 int8_t disp8() const {
78 assert(length_ >= 2);
79 return static_cast<int8_t>(encoding_[length_ - 1]);
80 }
81
82 int32_t disp32() const {
83 assert(length_ >= 5);
84 return bit_copy<int32_t>(encoding_[length_ - 4]);
85 }
86
87 Operand(const Operand &other) : length_(other.length_) {
88 memmove(&encoding_[0], &other.encoding_[0], other.length_);
89 }
90
91 Operand &operator=(const Operand &other) {
92 length_ = other.length_;
93 memmove(&encoding_[0], &other.encoding_[0], other.length_);
94 return *this;
95 }
96
97 bool Equals(const Operand &other) const {
98 if (length_ != other.length_)
99 return false;
100 for (uint8_t i = 0; i < length_; i++) {
101 if (encoding_[i] != other.encoding_[i])
102 return false;
103 }
104 return true;
105 }
106
107 protected:
108 Operand() : length_(0) {} // Needed by subclass Address.
109
110 void SetModRM(int mod, Register rm) {
111 assert((mod & ~3) == 0);
112 encoding_[0] = (mod << 6) | rm;
113 length_ = 1;
114 }
115
116 void SetSIB(ScaleFactor scale, Register index, Register base) {
117 assert(length_ == 1);
118 assert((scale & ~3) == 0);
119 encoding_[1] = (scale << 6) | (index << 3) | base;
120 length_ = 2;
121 }
122
123 void SetDisp8(int8_t disp) {
124 assert(length_ == 1 || length_ == 2);
125 encoding_[length_++] = static_cast<uint8_t>(disp);
126 }
127
128 void SetDisp32(int32_t disp) {
129 assert(length_ == 1 || length_ == 2);
130 intptr_t disp_size = sizeof(disp);
131 memmove(&encoding_[length_], &disp, disp_size);
132 length_ += disp_size;
133 }
134
135 private:
136 uint8_t length_;
137 uint8_t encoding_[6];
138 uint8_t padding_;
139
140 explicit Operand(Register reg) { SetModRM(3, reg); }
141
142 // Get the operand encoding byte at the given index.
143 uint8_t encoding_at(intptr_t index) const {
144 assert(index >= 0 && index < length_);
145 return encoding_[index];
146 }
147
148 // Returns whether or not this operand is really the given register in
149 // disguise. Used from the assembler to generate better encodings.
150 bool IsRegister(Register reg) const {
151 return ((encoding_[0] & 0xF8) == 0xC0) // Addressing mode is register only.
152 && ((encoding_[0] & 0x07) == reg); // Register codes match.
153 }
154
155 friend class AssemblerX86;
156 };
157
158 class Address : public Operand {
159 public:
160 Address(Register base, int32_t disp) {
161 if (disp == 0 && base != EBP) {
162 SetModRM(0, base);
163 if (base == ESP)
164 SetSIB(TIMES_1, ESP, base);
165 } else if (Utils::IsInt(8, disp)) {
166 SetModRM(1, base);
167 if (base == ESP)
168 SetSIB(TIMES_1, ESP, base);
169 SetDisp8(disp);
170 } else {
171 SetModRM(2, base);
172 if (base == ESP)
173 SetSIB(TIMES_1, ESP, base);
174 SetDisp32(disp);
175 }
176 }
177
178 Address(Register index, ScaleFactor scale, int32_t disp) {
179 assert(index != ESP); // Illegal addressing mode.
180 SetModRM(0, ESP);
181 SetSIB(scale, index, EBP);
182 SetDisp32(disp);
183 }
184
185 Address(Register base, Register index, ScaleFactor scale, int32_t disp) {
186 assert(index != ESP); // Illegal addressing mode.
187 if (disp == 0 && base != EBP) {
188 SetModRM(0, ESP);
189 SetSIB(scale, index, base);
190 } else if (Utils::IsInt(8, disp)) {
191 SetModRM(1, ESP);
192 SetSIB(scale, index, base);
193 SetDisp8(disp);
194 } else {
195 SetModRM(2, ESP);
196 SetSIB(scale, index, base);
197 SetDisp32(disp);
198 }
199 }
200
201 Address(const Address &other) : Operand(other) {}
202
203 Address &operator=(const Address &other) {
204 Operand::operator=(other);
205 return *this;
206 }
207
208 static Address Absolute(const uintptr_t addr) {
209 Address result;
210 result.SetModRM(0, EBP);
211 result.SetDisp32(addr);
212 return result;
213 }
214
215 private:
216 Address() {} // Needed by Address::Absolute.
217 };
218
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 // For integer operations that are strict on type.
302 typedef void (AssemblerX86::*EmitRegByteR)(Register, ByteRegister);
303 typedef void (AssemblerX86::*EmitRegReg)(Register, Register);
304 typedef void (AssemblerX86::*EmitRegAddr)(Register, const Address &);
305
306 // For the integer operations that are less strict on type.
307 // Make a version that is independent of the type and fudge a little
308 // and consider ByteRegister the same as Register.
309 typedef void (AssemblerX86::*EmitTyRegReg)(Type, Register, Register);
310 typedef void (AssemblerX86::*EmitTyRegImm)(Type, Register, const Immediate &);
311 typedef void (AssemblerX86::*EmitTyRegAddr)(Type, Register, const Address &);
312 typedef void (AssemblerX86::*EmitTyAddrReg)(Type, const Address &, Register);
313 typedef void (AssemblerX86::*EmitTyAddrImm)(Type, const Address &,
314 const Immediate &);
315
316 // For XMM operations.
317 typedef void (AssemblerX86::*EmitXmmXmm)(XmmRegister, XmmRegister);
318 typedef void (AssemblerX86::*EmitXmmAddr)(XmmRegister, const Address &);
319
320 /*
321 * Emit Machine Instructions.
322 */
323 void call(Register reg);
324 void call(const Address &address);
325 void call(Label *label);
326 void call(const ConstantRelocatable *label);
327
328 static const intptr_t kCallExternalLabelSize = 5;
329
330 void pushl(Register reg);
331 void pushl(const Address &address);
332 void pushl(const Immediate &imm);
333
334 void popl(Register reg);
335 void popl(const Address &address);
336
337 void pushal();
338 void popal();
339
340 void setcc(Condition condition, ByteRegister dst);
341
342 void movl(Register dst, const Immediate &src);
343 void movl(Register dst, Register src);
344
345 void movl(Register dst, const Address &src);
346 void movl(const Address &dst, Register src);
347 void movl(const Address &dst, const Immediate &imm);
348
349 void movzxb(Register dst, ByteRegister src);
350 void movzxb(Register dst, const Address &src);
351 void movsxb(Register dst, ByteRegister src);
352 void movsxb(Register dst, const Address &src);
353
354 void movb(ByteRegister dst, const Address &src);
355 void movb(const Address &dst, ByteRegister src);
356 void movb(const Address &dst, const Immediate &imm);
357
358 void movzxw(Register dst, Register src);
359 void movzxw(Register dst, const Address &src);
360 void movsxw(Register dst, Register src);
361 void movsxw(Register dst, const Address &src);
362 void movw(Register dst, const Address &src);
363 void movw(const Address &dst, Register src);
364
365 void leal(Register dst, const Address &src);
366
367 void cmov(Condition cond, Register dst, Register src);
368
369 void rep_movsb();
370
371 void movss(XmmRegister dst, const Address &src);
372 void movss(const Address &dst, XmmRegister src);
373 void movss(XmmRegister dst, XmmRegister src);
374
375 void movd(XmmRegister dst, Register src);
376 void movd(Register dst, XmmRegister src);
377
378 void movq(const Address &dst, XmmRegister src);
379 void movq(XmmRegister dst, const Address &src);
380
381 void addss(XmmRegister dst, XmmRegister src);
382 void addss(XmmRegister dst, const Address &src);
383 void subss(XmmRegister dst, XmmRegister src);
384 void subss(XmmRegister dst, const Address &src);
385 void mulss(XmmRegister dst, XmmRegister src);
386 void mulss(XmmRegister dst, const Address &src);
387 void divss(XmmRegister dst, XmmRegister src);
388 void divss(XmmRegister dst, const Address &src);
389
390 void movsd(XmmRegister dst, const Address &src);
391 void movsd(const Address &dst, XmmRegister src);
392 void movsd(XmmRegister dst, XmmRegister src);
393
394 void movaps(XmmRegister dst, XmmRegister src);
395
396 void movups(XmmRegister dst, const Address &src);
397 void movups(const Address &dst, XmmRegister src);
398
399 void addsd(XmmRegister dst, XmmRegister src);
400 void addsd(XmmRegister dst, const Address &src);
401 void subsd(XmmRegister dst, XmmRegister src);
402 void subsd(XmmRegister dst, const Address &src);
403 void mulsd(XmmRegister dst, XmmRegister src);
404 void mulsd(XmmRegister dst, const Address &src);
405 void divsd(XmmRegister dst, XmmRegister src);
406 void divsd(XmmRegister dst, const Address &src);
407
408 void addpl(XmmRegister dst, XmmRegister src);
409 void subpl(XmmRegister dst, XmmRegister src);
410 void addps(XmmRegister dst, XmmRegister src);
411 void addps(XmmRegister dst, const Address &src);
412 void subps(XmmRegister dst, XmmRegister src);
413 void subps(XmmRegister dst, const Address &src);
414 void divps(XmmRegister dst, XmmRegister src);
415 void divps(XmmRegister dst, const Address &src);
416 void mulps(XmmRegister dst, XmmRegister src);
417 void mulps(XmmRegister dst, const Address &src);
418 void minps(XmmRegister dst, XmmRegister src);
419 void maxps(XmmRegister dst, XmmRegister src);
420 void andps(XmmRegister dst, XmmRegister src);
421 void andps(XmmRegister dst, const Address &src);
422 void orps(XmmRegister dst, XmmRegister src);
423 void notps(XmmRegister dst);
424 void negateps(XmmRegister dst);
425 void absps(XmmRegister dst);
426 void zerowps(XmmRegister dst);
427
428 // TODO(jvoung): Use the enum type instead of uint8_t.
429 void cmpps(XmmRegister dst, XmmRegister src, uint8_t CmpCondition);
430 void cmpps(XmmRegister dst, const Address &src, uint8_t CmpCondition);
431
432 void sqrtps(XmmRegister dst);
433 void rsqrtps(XmmRegister dst);
434 void reciprocalps(XmmRegister dst);
435 void movhlps(XmmRegister dst, XmmRegister src);
436 void movlhps(XmmRegister dst, XmmRegister src);
437 void unpcklps(XmmRegister dst, XmmRegister src);
438 void unpckhps(XmmRegister dst, XmmRegister src);
439 void unpcklpd(XmmRegister dst, XmmRegister src);
440 void unpckhpd(XmmRegister dst, XmmRegister src);
441
442 void set1ps(XmmRegister dst, Register tmp, const Immediate &imm);
443 void shufps(XmmRegister dst, XmmRegister src, const Immediate &mask);
444
445 void addpd(XmmRegister dst, XmmRegister src);
446 void negatepd(XmmRegister dst);
447 void subpd(XmmRegister dst, XmmRegister src);
448 void mulpd(XmmRegister dst, XmmRegister src);
449 void divpd(XmmRegister dst, XmmRegister src);
450 void abspd(XmmRegister dst);
451 void minpd(XmmRegister dst, XmmRegister src);
452 void maxpd(XmmRegister dst, XmmRegister src);
453 void sqrtpd(XmmRegister dst);
454 void cvtps2pd(XmmRegister dst, XmmRegister src);
455 void cvtpd2ps(XmmRegister dst, XmmRegister src);
456 void shufpd(XmmRegister dst, XmmRegister src, const Immediate &mask);
457
458 void cvtsi2ss(XmmRegister dst, Register src);
459 void cvtsi2sd(XmmRegister dst, Register src);
460
461 void cvtss2si(Register dst, XmmRegister src);
462 void cvtss2sd(XmmRegister dst, XmmRegister src);
463
464 void cvtsd2si(Register dst, XmmRegister src);
465 void cvtsd2ss(XmmRegister dst, XmmRegister src);
466
467 void cvttss2si(Register dst, XmmRegister src);
468 void cvttsd2si(Register dst, XmmRegister src);
469
470 void cvtdq2pd(XmmRegister dst, XmmRegister src);
471
472 void ucomiss(XmmRegister a, XmmRegister b);
473 void ucomiss(XmmRegister a, const Address &b);
474 void ucomisd(XmmRegister a, XmmRegister b);
475 void ucomisd(XmmRegister a, const Address &b);
476
477 void movmskpd(Register dst, XmmRegister src);
478 void movmskps(Register dst, XmmRegister src);
479
480 void sqrtsd(XmmRegister dst, const Address &src);
481 void sqrtsd(XmmRegister dst, XmmRegister src);
482 void sqrtss(XmmRegister dst, const Address &src);
483 void sqrtss(XmmRegister dst, XmmRegister src);
484
485 void xorpd(XmmRegister dst, const Address &src);
486 void xorpd(XmmRegister dst, XmmRegister src);
487 void xorps(XmmRegister dst, const Address &src);
488 void xorps(XmmRegister dst, XmmRegister src);
489
490 void andpd(XmmRegister dst, const Address &src);
491 void andpd(XmmRegister dst, XmmRegister src);
492
493 void orpd(XmmRegister dst, XmmRegister src);
494
495 void pextrd(Register dst, XmmRegister src, const Immediate &imm);
496 void pmovsxdq(XmmRegister dst, XmmRegister src);
497 void pcmpeqq(XmmRegister dst, XmmRegister src);
498
499 void pxor(XmmRegister dst, XmmRegister src);
500
501 enum RoundingMode {
502 kRoundToNearest = 0x0,
503 kRoundDown = 0x1,
504 kRoundUp = 0x2,
505 kRoundToZero = 0x3
506 };
507 void roundsd(XmmRegister dst, XmmRegister src, RoundingMode mode);
508
509 void flds(const Address &src);
510 void fstps(const Address &dst);
511
512 void fldl(const Address &src);
513 void fstpl(const Address &dst);
514
515 void fnstcw(const Address &dst);
516 void fldcw(const Address &src);
517
518 void fistpl(const Address &dst);
519 void fistps(const Address &dst);
520 void fildl(const Address &src);
521 void filds(const Address &src);
522
523 void fincstp();
524
525 void xchgl(Register dst, Register src);
526
527 void cmp(Type Ty, Register reg, const Immediate &imm);
528 void cmp(Type Ty, Register reg0, Register reg1);
529 void cmp(Type Ty, Register reg, const Address &address);
530
531 void cmp(Type Ty, const Address &address, Register reg);
532 void cmp(Type Ty, const Address &address, const Immediate &imm);
533
534 void testl(Register reg1, Register reg2);
535 void testl(Register reg, const Immediate &imm);
536
537 void _and(Type Ty, Register dst, const Immediate &imm);
538 void _and(Type Ty, Register dst, Register src);
539 void _and(Type Ty, Register dst, const Address &address);
540
541 void _or(Type Ty, Register dst, const Immediate &imm);
542 void _or(Type Ty, Register dst, Register src);
543 void _or(Type Ty, Register dst, const Address &address);
544
545 void _xor(Type Ty, Register dst, const Immediate &imm);
546 void _xor(Type Ty, Register dst, Register src);
547 void _xor(Type Ty, Register dst, const Address &address);
548
549 // We fudge a little, and use Register for ByteRegister as well.
550 void add(Type Ty, Register dst, Register src);
551 void add(Type Ty, Register reg, const Immediate &imm);
552 void add(Type Ty, Register reg, const Address &address);
553
554 void add(Type Ty, const Address &address, Register reg);
555 void add(Type Ty, const Address &address, const Immediate &imm);
556
557 void adc(Type Ty, Register dst, Register src);
558 void adc(Type Ty, Register reg, const Immediate &imm);
559 void adc(Type Ty, Register dst, const Address &address);
560
561 void sub(Type Ty, Register dst, Register src);
562 void sub(Type Ty, Register reg, const Immediate &imm);
563 void sub(Type Ty, Register reg, const Address &address);
564
565 void cbw();
566 void cwd();
567 void cdq();
568
569 void idivl(Register reg);
570
571 void imull(Register dst, Register src);
572 void imull(Register reg, const Immediate &imm);
573 void imull(Register reg, const Address &address);
574
575 void imull(Register reg);
576 void imull(const Address &address);
577
578 void mull(Register reg);
579 void mull(const Address &address);
580
581 void sbb(Type Ty, Register dst, Register src);
582 void sbb(Type Ty, Register reg, const Immediate &imm);
583 void sbb(Type Ty, Register reg, const Address &address);
584
585 void incl(Register reg);
586 void incl(const Address &address);
587
588 void decl(Register reg);
589 void decl(const Address &address);
590
591 void shll(Register reg, const Immediate &imm);
592 void shll(Register operand, Register shifter);
593 void shll(const Address &operand, Register shifter);
594 void shrl(Register reg, const Immediate &imm);
595 void shrl(Register operand, Register shifter);
596 void sarl(Register reg, const Immediate &imm);
597 void sarl(Register operand, Register shifter);
598 void sarl(const Address &address, Register shifter);
599 void shld(Register dst, Register src);
600 void shld(Register dst, Register src, const Immediate &imm);
601 void shld(const Address &operand, Register src);
602 void shrd(Register dst, Register src);
603 void shrd(Register dst, Register src, const Immediate &imm);
604 void shrd(const Address &dst, Register src);
605
606 void negl(Register reg);
607 void notl(Register reg);
608
609 void bsrl(Register dst, Register src);
610
611 void bt(Register base, Register offset);
612
613 void enter(const Immediate &imm);
614 void leave();
615
616 void ret();
617 void ret(const Immediate &imm);
618
619 // 'size' indicates size in bytes and must be in the range 1..8.
620 void nop(int size = 1);
621 void int3();
622 // TODO(jvoung): should Subzero just use hlt instead of ud2?
623 void hlt();
624
625 void j(Condition condition, Label *label, bool near = kFarJump);
626 void j(Condition condition, const ConstantRelocatable *label);
627
628 void jmp(Register reg);
629 void jmp(Label *label, bool near = kFarJump);
630 void jmp(const ConstantRelocatable *label);
631
632 void lock();
633 void cmpxchgl(const Address &address, Register reg);
634
635 // TODO(jvoung): probably don't need this.
636 void cpuid();
637
638 /*
639 * Macros for High-level operations and implemented on all architectures.
640 * TODO(jvoung): Get rid of these?
641 * They are a bit smarter about checking the immediate size though.
642 */
643
644 void AddImmediate(Register reg, const Immediate &imm);
645 void SubImmediate(Register reg, const Immediate &imm);
646
647 void DoubleNegate(XmmRegister d);
648 void FloatNegate(XmmRegister f);
649
650 void DoubleAbs(XmmRegister reg);
651
652 void LockCmpxchgl(const Address &address, Register reg) {
653 lock();
654 cmpxchgl(address, reg);
655 }
656
657 intptr_t PreferredLoopAlignment() { return 16; }
658 void Align(intptr_t alignment, intptr_t offset);
659 void Bind(Label *label);
660
661 intptr_t CodeSize() const { return buffer_.Size(); }
662
663 void FinalizeInstructions(const MemoryRegion &region) {
664 buffer_.FinalizeInstructions(region);
665 }
666
667 // Expose the buffer, for bringup...
668 intptr_t GetPosition() const { return buffer_.GetPosition(); }
669 template <typename T> T LoadBuffer(intptr_t position) const {
670 return buffer_.Load<T>(position);
671 }
672
673 inline void EmitOperandSizeOverride();
674
675 private:
676 inline void EmitUint8(uint8_t value);
677 inline void EmitInt32(int32_t value);
678 inline void EmitRegisterOperand(int rm, int reg);
679 inline void EmitXmmRegisterOperand(int rm, XmmRegister reg);
680 inline void EmitFixup(AssemblerFixup *fixup);
681
682 void EmitOperand(int rm, const Operand &operand);
683 void EmitImmediate(const Immediate &imm);
684 void EmitComplexI8(int rm, const Operand &operand,
685 const Immediate &immediate);
686 void EmitComplex(int rm, const Operand &operand, const Immediate &immediate);
687 void EmitLabel(Label *label, intptr_t instruction_size);
688 void EmitLabelLink(Label *label);
689 void EmitNearLabelLink(Label *label);
690
691 void EmitGenericShift(int rm, Register reg, const Immediate &imm);
692 void EmitGenericShift(int rm, const Operand &operand, Register shifter);
693
694 AssemblerBuffer buffer_;
695
696 // DISALLOW_ALLOCATION(); // disables operator new.
697 AssemblerX86(const AssemblerX86 &) LLVM_DELETED_FUNCTION;
698 AssemblerX86 &operator=(const AssemblerX86 &) LLVM_DELETED_FUNCTION;
699 };
700
701 inline void AssemblerX86::EmitUint8(uint8_t value) {
702 buffer_.Emit<uint8_t>(value);
703 }
704
705 inline void AssemblerX86::EmitInt32(int32_t value) {
706 buffer_.Emit<int32_t>(value);
707 }
708
709 inline void AssemblerX86::EmitRegisterOperand(int rm, int reg) {
710 assert(rm >= 0 && rm < 8);
711 buffer_.Emit<uint8_t>(0xC0 + (rm << 3) + reg);
712 }
713
714 inline void AssemblerX86::EmitXmmRegisterOperand(int rm, XmmRegister reg) {
715 EmitRegisterOperand(rm, static_cast<Register>(reg));
716 }
717
718 inline void AssemblerX86::EmitFixup(AssemblerFixup *fixup) {
719 buffer_.EmitFixup(fixup);
720 }
721
722 inline void AssemblerX86::EmitOperandSizeOverride() { EmitUint8(0x66); }
723
724 } // end of namespace x86
725 } // end of namespace Ice
726
727 #endif // SUBZERO_SRC_ASSEMBLER_IA32_H_
OLDNEW
« src/IceUtils.h ('K') | « src/assembler_constants_ia32.h ('k') | src/assembler_ia32.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698