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

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: make fixups part of address 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
« no previous file with comments | « src/assembler_constants_ia32.h ('k') | src/assembler_ia32.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #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 DisplacementRelocation : public AssemblerFixup {
41 public:
42 static DisplacementRelocation *create(Assembler *Asm, FixupKind Kind,
43 const ConstantRelocatable *Sym) {
44 return new (Asm->Allocate<DisplacementRelocation>())
45 DisplacementRelocation(Kind, Sym);
46 }
47
48 void Process(const MemoryRegion &region, intptr_t position) {
49 (void)region;
50 (void)position;
51 llvm_unreachable("We might not be using this Process() method later.");
52 }
53
54 private:
55 DisplacementRelocation(FixupKind Kind, const ConstantRelocatable *Sym)
56 : AssemblerFixup(Kind, Sym) {}
57 };
58
59 class Immediate {
60 public:
61 explicit Immediate(int32_t value) : value_(value) {}
62
63 Immediate(const Immediate &other) : value_(other.value_) {}
64
65 int32_t value() const { return value_; }
66
67 bool is_int8() const { return Utils::IsInt(8, value_); }
68 bool is_uint8() const { return Utils::IsUint(8, value_); }
69 bool is_uint16() const { return Utils::IsUint(16, value_); }
70
71 private:
72 const int32_t value_;
73
74 // TODO(5411081): Add DISALLOW_COPY_AND_ASSIGN(Immediate) once the mac
75 // build issue is resolved.
76 // And remove the unnecessary copy constructor.
77 };
78
79 class Operand {
80 public:
81 uint8_t mod() const { return (encoding_at(0) >> 6) & 3; }
82
83 Register rm() const { return static_cast<Register>(encoding_at(0) & 7); }
84
85 ScaleFactor scale() const {
86 return static_cast<ScaleFactor>((encoding_at(1) >> 6) & 3);
87 }
88
89 Register index() const {
90 return static_cast<Register>((encoding_at(1) >> 3) & 7);
91 }
92
93 Register base() const { return static_cast<Register>(encoding_at(1) & 7); }
94
95 int8_t disp8() const {
96 assert(length_ >= 2);
97 return static_cast<int8_t>(encoding_[length_ - 1]);
98 }
99
100 int32_t disp32() const {
101 assert(length_ >= 5);
102 return bit_copy<int32_t>(encoding_[length_ - 4]);
103 }
104
105 AssemblerFixup *fixup() const { return fixup_; }
106
107 Operand(const Operand &other) : length_(other.length_), fixup_(other.fixup_) {
108 memmove(&encoding_[0], &other.encoding_[0], other.length_);
109 }
110
111 Operand &operator=(const Operand &other) {
112 length_ = other.length_;
113 fixup_ = other.fixup_;
114 memmove(&encoding_[0], &other.encoding_[0], other.length_);
115 return *this;
116 }
117
118 protected:
119 Operand() : length_(0), fixup_(NULL) {} // Needed by subclass Address.
120
121 void SetModRM(int mod, Register rm) {
122 assert((mod & ~3) == 0);
123 encoding_[0] = (mod << 6) | rm;
124 length_ = 1;
125 }
126
127 void SetSIB(ScaleFactor scale, Register index, Register base) {
128 assert(length_ == 1);
129 assert((scale & ~3) == 0);
130 encoding_[1] = (scale << 6) | (index << 3) | base;
131 length_ = 2;
132 }
133
134 void SetDisp8(int8_t disp) {
135 assert(length_ == 1 || length_ == 2);
136 encoding_[length_++] = static_cast<uint8_t>(disp);
137 }
138
139 void SetDisp32(int32_t disp) {
140 assert(length_ == 1 || length_ == 2);
141 intptr_t disp_size = sizeof(disp);
142 memmove(&encoding_[length_], &disp, disp_size);
143 length_ += disp_size;
144 }
145
146 void SetFixup(AssemblerFixup *fixup) { fixup_ = fixup; }
147
148 private:
149 uint8_t length_;
150 uint8_t encoding_[6];
151 uint8_t padding_;
152 AssemblerFixup *fixup_;
153
154 explicit Operand(Register reg) : fixup_(NULL) { SetModRM(3, reg); }
155
156 // Get the operand encoding byte at the given index.
157 uint8_t encoding_at(intptr_t index) const {
158 assert(index >= 0 && index < length_);
159 return encoding_[index];
160 }
161
162 // Returns whether or not this operand is really the given register in
163 // disguise. Used from the assembler to generate better encodings.
164 bool IsRegister(Register reg) const {
165 return ((encoding_[0] & 0xF8) == 0xC0) // Addressing mode is register only.
166 && ((encoding_[0] & 0x07) == reg); // Register codes match.
167 }
168
169 friend class AssemblerX86;
170 };
171
172 class Address : public Operand {
173 public:
174 Address(Register base, int32_t disp) {
175 if (disp == 0 && base != EBP) {
176 SetModRM(0, base);
177 if (base == ESP)
178 SetSIB(TIMES_1, ESP, base);
179 } else if (Utils::IsInt(8, disp)) {
180 SetModRM(1, base);
181 if (base == ESP)
182 SetSIB(TIMES_1, ESP, base);
183 SetDisp8(disp);
184 } else {
185 SetModRM(2, base);
186 if (base == ESP)
187 SetSIB(TIMES_1, ESP, base);
188 SetDisp32(disp);
189 }
190 }
191
192 Address(Register index, ScaleFactor scale, int32_t disp) {
193 assert(index != ESP); // Illegal addressing mode.
194 SetModRM(0, ESP);
195 SetSIB(scale, index, EBP);
196 SetDisp32(disp);
197 }
198
199 Address(Register base, Register index, ScaleFactor scale, int32_t disp) {
200 assert(index != ESP); // Illegal addressing mode.
201 if (disp == 0 && base != EBP) {
202 SetModRM(0, ESP);
203 SetSIB(scale, index, base);
204 } else if (Utils::IsInt(8, disp)) {
205 SetModRM(1, ESP);
206 SetSIB(scale, index, base);
207 SetDisp8(disp);
208 } else {
209 SetModRM(2, ESP);
210 SetSIB(scale, index, base);
211 SetDisp32(disp);
212 }
213 }
214
215 Address(const Address &other) : Operand(other) {}
216
217 Address &operator=(const Address &other) {
218 Operand::operator=(other);
219 return *this;
220 }
221
222 static Address Absolute(const uintptr_t addr, AssemblerFixup *fixup) {
223 Address result;
224 result.SetModRM(0, EBP);
225 result.SetDisp32(addr);
226 result.SetFixup(fixup);
227 return result;
228 }
229
230 private:
231 Address() {} // Needed by Address::Absolute.
232 };
233
234 class Label {
235 public:
236 Label() : position_(0), num_unresolved_(0) {
237 #ifdef DEBUG
238 for (int i = 0; i < kMaxUnresolvedBranches; i++) {
239 unresolved_near_positions_[i] = -1;
240 }
241 #endif // DEBUG
242 }
243
244 ~Label() {
245 // Assert if label is being destroyed with unresolved branches pending.
246 assert(!IsLinked());
247 assert(!HasNear());
248 }
249
250 // TODO(jvoung): why are labels offset by this?
251 static const uint32_t kWordSize = sizeof(uint32_t);
252
253 // Returns the position for bound labels (branches that come after this
254 // are considered backward branches). Cannot be used for unused or linked
255 // labels.
256 intptr_t Position() const {
257 assert(IsBound());
258 return -position_ - kWordSize;
259 }
260
261 // Returns the position of an earlier branch instruction that was linked
262 // to this label (branches that use this are considered forward branches).
263 // The linked instructions form a linked list, of sorts, using the
264 // instruction's displacement field for the location of the next
265 // instruction that is also linked to this label.
266 intptr_t LinkPosition() const {
267 assert(IsLinked());
268 return position_ - kWordSize;
269 }
270
271 // Returns the position of an earlier branch instruction which
272 // assumes that this label is "near", and bumps iterator to the
273 // next near position.
274 intptr_t NearPosition() {
275 assert(HasNear());
276 return unresolved_near_positions_[--num_unresolved_];
277 }
278
279 bool IsBound() const { return position_ < 0; }
280 bool IsLinked() const { return position_ > 0; }
281 bool IsUnused() const { return (position_ == 0) && (num_unresolved_ == 0); }
282 bool HasNear() const { return num_unresolved_ != 0; }
283
284 private:
285 void BindTo(intptr_t position) {
286 assert(!IsBound());
287 assert(!HasNear());
288 position_ = -position - kWordSize;
289 assert(IsBound());
290 }
291
292 void LinkTo(intptr_t position) {
293 assert(!IsBound());
294 position_ = position + kWordSize;
295 assert(IsLinked());
296 }
297
298 void NearLinkTo(intptr_t position) {
299 assert(!IsBound());
300 assert(num_unresolved_ < kMaxUnresolvedBranches);
301 unresolved_near_positions_[num_unresolved_++] = position;
302 }
303
304 static const int kMaxUnresolvedBranches = 20;
305
306 intptr_t position_;
307 intptr_t num_unresolved_;
308 intptr_t unresolved_near_positions_[kMaxUnresolvedBranches];
309
310 friend class AssemblerX86;
311 Label(const Label &) LLVM_DELETED_FUNCTION;
312 Label &operator=(const Label &) LLVM_DELETED_FUNCTION;
313 };
314
315 class AssemblerX86 : public Assembler {
316 public:
317 explicit AssemblerX86(bool use_far_branches = false) : buffer_(*this) {
318 // This mode is only needed and implemented for MIPS and ARM.
319 assert(!use_far_branches);
320 }
321 ~AssemblerX86() {}
322
323 static const bool kNearJump = true;
324 static const bool kFarJump = false;
325
326 // For integer operations that are strict on type.
327 typedef void (AssemblerX86::*EmitRegByteR)(Register, ByteRegister);
328 typedef void (AssemblerX86::*EmitRegReg)(Register, Register);
329 typedef void (AssemblerX86::*EmitRegAddr)(Register, const Address &);
330
331 // For the integer operations that are less strict on type.
332 // Make a version that is independent of the type and fudge a little
333 // and consider ByteRegister the same as Register.
334 typedef void (AssemblerX86::*EmitTyRegReg)(Type, Register, Register);
335 typedef void (AssemblerX86::*EmitTyRegImm)(Type, Register, const Immediate &);
336 typedef void (AssemblerX86::*EmitTyRegAddr)(Type, Register, const Address &);
337 typedef void (AssemblerX86::*EmitTyAddrReg)(Type, const Address &, Register);
338 typedef void (AssemblerX86::*EmitTyAddrImm)(Type, const Address &,
339 const Immediate &);
340
341 // For XMM operations.
342 typedef void (AssemblerX86::*EmitXmmXmm)(XmmRegister, XmmRegister);
343 typedef void (AssemblerX86::*EmitXmmAddr)(XmmRegister, const Address &);
344 typedef void (AssemblerX86::*EmitAddrXmm)(const Address &, XmmRegister);
345
346 typedef void (AssemblerX86::*EmitTyXmmXmm)(Type, XmmRegister, XmmRegister);
347 typedef void (AssemblerX86::*EmitTyXmmAddr)(Type, XmmRegister,
348 const Address &);
349 typedef void (AssemblerX86::*EmitTyAddrXmm)(Type, const Address &,
350 XmmRegister);
351
352 /*
353 * Emit Machine Instructions.
354 */
355 void call(Register reg);
356 void call(const Address &address);
357 void call(Label *label);
358 void call(const ConstantRelocatable *label);
359
360 static const intptr_t kCallExternalLabelSize = 5;
361
362 void pushl(Register reg);
363 void pushl(const Address &address);
364 void pushl(const Immediate &imm);
365
366 void popl(Register reg);
367 void popl(const Address &address);
368
369 void pushal();
370 void popal();
371
372 void setcc(Condition condition, ByteRegister dst);
373
374 void movl(Register dst, const Immediate &src);
375 void movl(Register dst, Register src);
376
377 void movl(Register dst, const Address &src);
378 void movl(const Address &dst, Register src);
379 void movl(const Address &dst, const Immediate &imm);
380
381 void movzxb(Register dst, ByteRegister src);
382 void movzxb(Register dst, const Address &src);
383 void movsxb(Register dst, ByteRegister src);
384 void movsxb(Register dst, const Address &src);
385
386 void movb(ByteRegister dst, const Address &src);
387 void movb(const Address &dst, ByteRegister src);
388 void movb(const Address &dst, const Immediate &imm);
389
390 void movzxw(Register dst, Register src);
391 void movzxw(Register dst, const Address &src);
392 void movsxw(Register dst, Register src);
393 void movsxw(Register dst, const Address &src);
394 void movw(Register dst, const Address &src);
395 void movw(const Address &dst, Register src);
396
397 void leal(Register dst, const Address &src);
398
399 void cmov(Condition cond, Register dst, Register src);
400
401 void rep_movsb();
402
403 void movss(XmmRegister dst, const Address &src);
404 void movss(const Address &dst, XmmRegister src);
405 void movss(XmmRegister dst, XmmRegister src);
406
407 void movd(XmmRegister dst, Register src);
408 void movd(Register dst, XmmRegister src);
409
410 void movq(const Address &dst, XmmRegister src);
411 void movq(XmmRegister dst, const Address &src);
412
413 void addss(XmmRegister dst, XmmRegister src);
414 void addss(XmmRegister dst, const Address &src);
415 void subss(XmmRegister dst, XmmRegister src);
416 void subss(XmmRegister dst, const Address &src);
417 void mulss(XmmRegister dst, XmmRegister src);
418 void mulss(XmmRegister dst, const Address &src);
419 void divss(XmmRegister dst, XmmRegister src);
420 void divss(XmmRegister dst, const Address &src);
421
422 void movsd(XmmRegister dst, const Address &src);
423 void movsd(const Address &dst, XmmRegister src);
424 void movsd(XmmRegister dst, XmmRegister src);
425
426 void movaps(XmmRegister dst, XmmRegister src);
427
428 void movups(XmmRegister dst, const Address &src);
429 void movups(const Address &dst, XmmRegister src);
430
431 void addsd(XmmRegister dst, XmmRegister src);
432 void addsd(XmmRegister dst, const Address &src);
433 void subsd(XmmRegister dst, XmmRegister src);
434 void subsd(XmmRegister dst, const Address &src);
435 void mulsd(XmmRegister dst, XmmRegister src);
436 void mulsd(XmmRegister dst, const Address &src);
437 void divsd(XmmRegister dst, XmmRegister src);
438 void divsd(XmmRegister dst, const Address &src);
439
440 void padd(Type Ty, XmmRegister dst, XmmRegister src);
441 void padd(Type Ty, XmmRegister dst, const Address &src);
442 void psub(Type Ty, XmmRegister dst, XmmRegister src);
443 void psub(Type Ty, XmmRegister dst, const Address &src);
444
445 void addps(XmmRegister dst, XmmRegister src);
446 void addps(XmmRegister dst, const Address &src);
447 void subps(XmmRegister dst, XmmRegister src);
448 void subps(XmmRegister dst, const Address &src);
449 void divps(XmmRegister dst, XmmRegister src);
450 void divps(XmmRegister dst, const Address &src);
451 void mulps(XmmRegister dst, XmmRegister src);
452 void mulps(XmmRegister dst, const Address &src);
453 void minps(XmmRegister dst, XmmRegister src);
454 void maxps(XmmRegister dst, XmmRegister src);
455 void andps(XmmRegister dst, XmmRegister src);
456 void andps(XmmRegister dst, const Address &src);
457 void orps(XmmRegister dst, XmmRegister src);
458
459 // TODO(jvoung): Use the enum type instead of uint8_t.
460 void cmpps(XmmRegister dst, XmmRegister src, uint8_t CmpCondition);
461 void cmpps(XmmRegister dst, const Address &src, uint8_t CmpCondition);
462
463 void sqrtps(XmmRegister dst);
464 void rsqrtps(XmmRegister dst);
465 void reciprocalps(XmmRegister dst);
466 void movhlps(XmmRegister dst, XmmRegister src);
467 void movlhps(XmmRegister dst, XmmRegister src);
468 void unpcklps(XmmRegister dst, XmmRegister src);
469 void unpckhps(XmmRegister dst, XmmRegister src);
470 void unpcklpd(XmmRegister dst, XmmRegister src);
471 void unpckhpd(XmmRegister dst, XmmRegister src);
472
473 void set1ps(XmmRegister dst, Register tmp, const Immediate &imm);
474 void shufps(XmmRegister dst, XmmRegister src, const Immediate &mask);
475
476 void addpd(XmmRegister dst, XmmRegister src);
477 void subpd(XmmRegister dst, XmmRegister src);
478 void mulpd(XmmRegister dst, XmmRegister src);
479 void divpd(XmmRegister dst, XmmRegister src);
480 void minpd(XmmRegister dst, XmmRegister src);
481 void maxpd(XmmRegister dst, XmmRegister src);
482 void sqrtpd(XmmRegister dst);
483 void cvtps2pd(XmmRegister dst, XmmRegister src);
484 void cvtpd2ps(XmmRegister dst, XmmRegister src);
485 void shufpd(XmmRegister dst, XmmRegister src, const Immediate &mask);
486
487 void cvtsi2ss(XmmRegister dst, Register src);
488 void cvtsi2sd(XmmRegister dst, Register src);
489
490 void cvtss2si(Register dst, XmmRegister src);
491 void cvtss2sd(XmmRegister dst, XmmRegister src);
492
493 void cvtsd2si(Register dst, XmmRegister src);
494 void cvtsd2ss(XmmRegister dst, XmmRegister src);
495
496 void cvttss2si(Register dst, XmmRegister src);
497 void cvttsd2si(Register dst, XmmRegister src);
498
499 void cvtdq2pd(XmmRegister dst, XmmRegister src);
500
501 void ucomiss(XmmRegister a, XmmRegister b);
502 void ucomiss(XmmRegister a, const Address &b);
503 void ucomisd(XmmRegister a, XmmRegister b);
504 void ucomisd(XmmRegister a, const Address &b);
505
506 void movmskpd(Register dst, XmmRegister src);
507 void movmskps(Register dst, XmmRegister src);
508
509 void sqrtsd(XmmRegister dst, const Address &src);
510 void sqrtsd(XmmRegister dst, XmmRegister src);
511 void sqrtss(XmmRegister dst, const Address &src);
512 void sqrtss(XmmRegister dst, XmmRegister src);
513
514 void xorpd(XmmRegister dst, const Address &src);
515 void xorpd(XmmRegister dst, XmmRegister src);
516 void xorps(XmmRegister dst, const Address &src);
517 void xorps(XmmRegister dst, XmmRegister src);
518
519 void andpd(XmmRegister dst, const Address &src);
520 void andpd(XmmRegister dst, XmmRegister src);
521
522 void orpd(XmmRegister dst, XmmRegister src);
523
524 void pextrd(Register dst, XmmRegister src, const Immediate &imm);
525 void pmovsxdq(XmmRegister dst, XmmRegister src);
526 void pcmpeqq(XmmRegister dst, XmmRegister src);
527
528 void pxor(XmmRegister dst, XmmRegister src);
529
530 enum RoundingMode {
531 kRoundToNearest = 0x0,
532 kRoundDown = 0x1,
533 kRoundUp = 0x2,
534 kRoundToZero = 0x3
535 };
536 void roundsd(XmmRegister dst, XmmRegister src, RoundingMode mode);
537
538 void flds(const Address &src);
539 void fstps(const Address &dst);
540
541 void fldl(const Address &src);
542 void fstpl(const Address &dst);
543
544 void fnstcw(const Address &dst);
545 void fldcw(const Address &src);
546
547 void fistpl(const Address &dst);
548 void fistps(const Address &dst);
549 void fildl(const Address &src);
550 void filds(const Address &src);
551
552 void fincstp();
553
554 void xchgl(Register dst, Register src);
555
556 void cmp(Type Ty, Register reg, const Immediate &imm);
557 void cmp(Type Ty, Register reg0, Register reg1);
558 void cmp(Type Ty, Register reg, const Address &address);
559
560 void cmp(Type Ty, const Address &address, Register reg);
561 void cmp(Type Ty, const Address &address, const Immediate &imm);
562
563 void testl(Register reg1, Register reg2);
564 void testl(Register reg, const Immediate &imm);
565
566 void _and(Type Ty, Register dst, const Immediate &imm);
567 void _and(Type Ty, Register dst, Register src);
568 void _and(Type Ty, Register dst, const Address &address);
569
570 void _or(Type Ty, Register dst, const Immediate &imm);
571 void _or(Type Ty, Register dst, Register src);
572 void _or(Type Ty, Register dst, const Address &address);
573
574 void _xor(Type Ty, Register dst, const Immediate &imm);
575 void _xor(Type Ty, Register dst, Register src);
576 void _xor(Type Ty, Register dst, const Address &address);
577
578 // We fudge a little, and use Register for ByteRegister as well.
579 void add(Type Ty, Register dst, Register src);
580 void add(Type Ty, Register reg, const Immediate &imm);
581 void add(Type Ty, Register reg, const Address &address);
582
583 void add(Type Ty, const Address &address, Register reg);
584 void add(Type Ty, const Address &address, const Immediate &imm);
585
586 void adc(Type Ty, Register dst, Register src);
587 void adc(Type Ty, Register reg, const Immediate &imm);
588 void adc(Type Ty, Register dst, const Address &address);
589
590 void sub(Type Ty, Register dst, Register src);
591 void sub(Type Ty, Register reg, const Immediate &imm);
592 void sub(Type Ty, Register reg, const Address &address);
593
594 void cbw();
595 void cwd();
596 void cdq();
597
598 void idivl(Register reg);
599
600 void imull(Register dst, Register src);
601 void imull(Register reg, const Immediate &imm);
602 void imull(Register reg, const Address &address);
603
604 void imull(Register reg);
605 void imull(const Address &address);
606
607 void mull(Register reg);
608 void mull(const Address &address);
609
610 void sbb(Type Ty, Register dst, Register src);
611 void sbb(Type Ty, Register reg, const Immediate &imm);
612 void sbb(Type Ty, Register reg, const Address &address);
613
614 void incl(Register reg);
615 void incl(const Address &address);
616
617 void decl(Register reg);
618 void decl(const Address &address);
619
620 void shll(Register reg, const Immediate &imm);
621 void shll(Register operand, Register shifter);
622 void shll(const Address &operand, Register shifter);
623 void shrl(Register reg, const Immediate &imm);
624 void shrl(Register operand, Register shifter);
625 void sarl(Register reg, const Immediate &imm);
626 void sarl(Register operand, Register shifter);
627 void sarl(const Address &address, Register shifter);
628 void shld(Register dst, Register src);
629 void shld(Register dst, Register src, const Immediate &imm);
630 void shld(const Address &operand, Register src);
631 void shrd(Register dst, Register src);
632 void shrd(Register dst, Register src, const Immediate &imm);
633 void shrd(const Address &dst, Register src);
634
635 void negl(Register reg);
636 void notl(Register reg);
637
638 void bsrl(Register dst, Register src);
639
640 void bt(Register base, Register offset);
641
642 void enter(const Immediate &imm);
643 void leave();
644
645 void ret();
646 void ret(const Immediate &imm);
647
648 // 'size' indicates size in bytes and must be in the range 1..8.
649 void nop(int size = 1);
650 void int3();
651 // TODO(jvoung): should Subzero just use hlt instead of ud2?
652 void hlt();
653
654 void j(Condition condition, Label *label, bool near = kFarJump);
655 void j(Condition condition, const ConstantRelocatable *label);
656
657 void jmp(Register reg);
658 void jmp(Label *label, bool near = kFarJump);
659 void jmp(const ConstantRelocatable *label);
660
661 void lock();
662 void cmpxchgl(const Address &address, Register reg);
663
664 void LockCmpxchgl(const Address &address, Register reg) {
665 lock();
666 cmpxchgl(address, reg);
667 }
668
669 intptr_t PreferredLoopAlignment() { return 16; }
670 void Align(intptr_t alignment, intptr_t offset);
671 void Bind(Label *label);
672
673 intptr_t CodeSize() const { return buffer_.Size(); }
674
675 void FinalizeInstructions(const MemoryRegion &region) {
676 buffer_.FinalizeInstructions(region);
677 }
678
679 // Expose the buffer, for bringup...
680 intptr_t GetPosition() const { return buffer_.GetPosition(); }
681 template <typename T> T LoadBuffer(intptr_t position) const {
682 return buffer_.Load<T>(position);
683 }
684 AssemblerFixup *GetLatestFixup() const { return buffer_.GetLatestFixup(); }
685
686 private:
687 inline void EmitUint8(uint8_t value);
688 inline void EmitInt32(int32_t value);
689 inline void EmitRegisterOperand(int rm, int reg);
690 inline void EmitXmmRegisterOperand(int rm, XmmRegister reg);
691 inline void EmitFixup(AssemblerFixup *fixup);
692 inline void EmitOperandSizeOverride();
693
694 void EmitOperand(int rm, const Operand &operand);
695 void EmitImmediate(const Immediate &imm);
696 void EmitComplexI8(int rm, const Operand &operand,
697 const Immediate &immediate);
698 void EmitComplex(int rm, const Operand &operand, const Immediate &immediate);
699 void EmitLabel(Label *label, intptr_t instruction_size);
700 void EmitLabelLink(Label *label);
701 void EmitNearLabelLink(Label *label);
702
703 void EmitGenericShift(int rm, Register reg, const Immediate &imm);
704 void EmitGenericShift(int rm, const Operand &operand, Register shifter);
705
706 AssemblerBuffer buffer_;
707
708 // DISALLOW_ALLOCATION(); // disables operator new.
709 AssemblerX86(const AssemblerX86 &) LLVM_DELETED_FUNCTION;
710 AssemblerX86 &operator=(const AssemblerX86 &) LLVM_DELETED_FUNCTION;
711 };
712
713 inline void AssemblerX86::EmitUint8(uint8_t value) {
714 buffer_.Emit<uint8_t>(value);
715 }
716
717 inline void AssemblerX86::EmitInt32(int32_t value) {
718 buffer_.Emit<int32_t>(value);
719 }
720
721 inline void AssemblerX86::EmitRegisterOperand(int rm, int reg) {
722 assert(rm >= 0 && rm < 8);
723 buffer_.Emit<uint8_t>(0xC0 + (rm << 3) + reg);
724 }
725
726 inline void AssemblerX86::EmitXmmRegisterOperand(int rm, XmmRegister reg) {
727 EmitRegisterOperand(rm, static_cast<Register>(reg));
728 }
729
730 inline void AssemblerX86::EmitFixup(AssemblerFixup *fixup) {
731 buffer_.EmitFixup(fixup);
732 }
733
734 inline void AssemblerX86::EmitOperandSizeOverride() { EmitUint8(0x66); }
735
736 } // end of namespace x86
737 } // end of namespace Ice
738
739 #endif // SUBZERO_SRC_ASSEMBLER_IA32_H_
OLDNEW
« no previous file with comments | « 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