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

Side by Side Diff: src/assembler_ia32.h

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

Powered by Google App Engine
This is Rietveld 408576698