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

Side by Side Diff: src/assembler_ia32.h

Issue 1179563004: Renames the assembler* files. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Changes the top comment for IceAssemblerX8632.cpp Created 5 years, 6 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_arm32.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 //===- subzero/src/assembler_ia32.h - Assembler for x86-32 ------*- C++ -*-===//
2 //
3 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
4 // for details. All rights reserved. Use of this source code is governed by a
5 // BSD-style license that can be found in the LICENSE file.
6 //
7 // Modified by the Subzero authors.
8 //
9 //===----------------------------------------------------------------------===//
10 //
11 // The Subzero Code Generator
12 //
13 // This file is distributed under the University of Illinois Open Source
14 // License. See LICENSE.TXT for details.
15 //
16 //===----------------------------------------------------------------------===//
17 //
18 // This file implements the Assembler class for x86-32.
19 //
20 //===----------------------------------------------------------------------===//
21
22 #ifndef SUBZERO_SRC_ASSEMBLER_IA32_H
23 #define SUBZERO_SRC_ASSEMBLER_IA32_H
24
25 #include "IceConditionCodesX8632.h"
26 #include "IceDefs.h"
27 #include "IceOperand.h"
28 #include "IceRegistersX8632.h"
29 #include "IceTypes.h"
30 #include "IceUtils.h"
31
32 #include "assembler.h"
33
34 namespace Ice {
35
36 using RegX8632::GPRRegister;
37 using RegX8632::XmmRegister;
38 using RegX8632::ByteRegister;
39 using RegX8632::X87STRegister;
40
41 namespace X8632 {
42
43 const int MAX_NOP_SIZE = 8;
44
45 enum ScaleFactor { TIMES_1 = 0, TIMES_2 = 1, TIMES_4 = 2, TIMES_8 = 3 };
46
47 class Immediate {
48 Immediate(const Immediate &) = delete;
49 Immediate &operator=(const Immediate &) = delete;
50
51 public:
52 explicit Immediate(int32_t value) : value_(value), fixup_(nullptr) {}
53
54 Immediate(RelocOffsetT offset, AssemblerFixup *fixup)
55 : value_(offset), fixup_(fixup) {
56 // Use the Offset in the "value" for now. If we decide to process fixups,
57 // we'll need to patch that offset with the true value.
58 }
59
60 int32_t value() const { return value_; }
61 AssemblerFixup *fixup() const { return fixup_; }
62
63 bool is_int8() const {
64 // We currently only allow 32-bit fixups, and they usually have value = 0,
65 // so if fixup_ != nullptr, it shouldn't be classified as int8/16.
66 return fixup_ == nullptr && Utils::IsInt(8, value_);
67 }
68 bool is_uint8() const {
69 return fixup_ == nullptr && Utils::IsUint(8, value_);
70 }
71 bool is_uint16() const {
72 return fixup_ == nullptr && Utils::IsUint(16, value_);
73 }
74
75 private:
76 const int32_t value_;
77 AssemblerFixup *fixup_;
78 };
79
80 class Operand {
81 public:
82 Operand(const Operand &other) : length_(other.length_), fixup_(other.fixup_) {
83 memmove(&encoding_[0], &other.encoding_[0], other.length_);
84 }
85
86 Operand &operator=(const Operand &other) {
87 length_ = other.length_;
88 fixup_ = other.fixup_;
89 memmove(&encoding_[0], &other.encoding_[0], other.length_);
90 return *this;
91 }
92
93 uint8_t mod() const { return (encoding_at(0) >> 6) & 3; }
94
95 GPRRegister rm() const {
96 return static_cast<GPRRegister>(encoding_at(0) & 7);
97 }
98
99 ScaleFactor scale() const {
100 return static_cast<ScaleFactor>((encoding_at(1) >> 6) & 3);
101 }
102
103 GPRRegister index() const {
104 return static_cast<GPRRegister>((encoding_at(1) >> 3) & 7);
105 }
106
107 GPRRegister base() const {
108 return static_cast<GPRRegister>(encoding_at(1) & 7);
109 }
110
111 int8_t disp8() const {
112 assert(length_ >= 2);
113 return static_cast<int8_t>(encoding_[length_ - 1]);
114 }
115
116 int32_t disp32() const {
117 assert(length_ >= 5);
118 return bit_copy<int32_t>(encoding_[length_ - 4]);
119 }
120
121 AssemblerFixup *fixup() const { return fixup_; }
122
123 protected:
124 Operand() : length_(0), fixup_(nullptr) {} // Needed by subclass Address.
125
126 void SetModRM(int mod, GPRRegister rm) {
127 assert((mod & ~3) == 0);
128 encoding_[0] = (mod << 6) | rm;
129 length_ = 1;
130 }
131
132 void SetSIB(ScaleFactor scale, GPRRegister index, GPRRegister base) {
133 assert(length_ == 1);
134 assert((scale & ~3) == 0);
135 encoding_[1] = (scale << 6) | (index << 3) | base;
136 length_ = 2;
137 }
138
139 void SetDisp8(int8_t disp) {
140 assert(length_ == 1 || length_ == 2);
141 encoding_[length_++] = static_cast<uint8_t>(disp);
142 }
143
144 void SetDisp32(int32_t disp) {
145 assert(length_ == 1 || length_ == 2);
146 intptr_t disp_size = sizeof(disp);
147 memmove(&encoding_[length_], &disp, disp_size);
148 length_ += disp_size;
149 }
150
151 void SetFixup(AssemblerFixup *fixup) { fixup_ = fixup; }
152
153 private:
154 uint8_t length_;
155 uint8_t encoding_[6];
156 AssemblerFixup *fixup_;
157
158 explicit Operand(GPRRegister reg) : fixup_(nullptr) { SetModRM(3, reg); }
159
160 // Get the operand encoding byte at the given index.
161 uint8_t encoding_at(intptr_t index) const {
162 assert(index >= 0 && index < length_);
163 return encoding_[index];
164 }
165
166 // Returns whether or not this operand is really the given register in
167 // disguise. Used from the assembler to generate better encodings.
168 bool IsRegister(GPRRegister reg) const {
169 return ((encoding_[0] & 0xF8) == 0xC0) // Addressing mode is register only.
170 && ((encoding_[0] & 0x07) == reg); // Register codes match.
171 }
172
173 friend class AssemblerX8632;
174 };
175
176 class Address : public Operand {
177 public:
178 Address(const Address &other) : Operand(other) {}
179
180 Address &operator=(const Address &other) {
181 Operand::operator=(other);
182 return *this;
183 }
184
185 Address(GPRRegister base, int32_t disp) {
186 if (disp == 0 && base != RegX8632::Encoded_Reg_ebp) {
187 SetModRM(0, base);
188 if (base == RegX8632::Encoded_Reg_esp)
189 SetSIB(TIMES_1, RegX8632::Encoded_Reg_esp, base);
190 } else if (Utils::IsInt(8, disp)) {
191 SetModRM(1, base);
192 if (base == RegX8632::Encoded_Reg_esp)
193 SetSIB(TIMES_1, RegX8632::Encoded_Reg_esp, base);
194 SetDisp8(disp);
195 } else {
196 SetModRM(2, base);
197 if (base == RegX8632::Encoded_Reg_esp)
198 SetSIB(TIMES_1, RegX8632::Encoded_Reg_esp, base);
199 SetDisp32(disp);
200 }
201 }
202
203 Address(GPRRegister index, ScaleFactor scale, int32_t disp) {
204 assert(index != RegX8632::Encoded_Reg_esp); // Illegal addressing mode.
205 SetModRM(0, RegX8632::Encoded_Reg_esp);
206 SetSIB(scale, index, RegX8632::Encoded_Reg_ebp);
207 SetDisp32(disp);
208 }
209
210 Address(GPRRegister base, GPRRegister index, ScaleFactor scale,
211 int32_t disp) {
212 assert(index != RegX8632::Encoded_Reg_esp); // Illegal addressing mode.
213 if (disp == 0 && base != RegX8632::Encoded_Reg_ebp) {
214 SetModRM(0, RegX8632::Encoded_Reg_esp);
215 SetSIB(scale, index, base);
216 } else if (Utils::IsInt(8, disp)) {
217 SetModRM(1, RegX8632::Encoded_Reg_esp);
218 SetSIB(scale, index, base);
219 SetDisp8(disp);
220 } else {
221 SetModRM(2, RegX8632::Encoded_Reg_esp);
222 SetSIB(scale, index, base);
223 SetDisp32(disp);
224 }
225 }
226
227 static Address Absolute(const uintptr_t addr) {
228 Address result;
229 result.SetModRM(0, RegX8632::Encoded_Reg_ebp);
230 result.SetDisp32(addr);
231 return result;
232 }
233
234 static Address Absolute(RelocOffsetT Offset, AssemblerFixup *fixup) {
235 Address result;
236 result.SetModRM(0, RegX8632::Encoded_Reg_ebp);
237 // Use the Offset in the displacement for now. If we decide to process
238 // fixups later, we'll need to patch up the emitted displacement.
239 result.SetDisp32(Offset);
240 result.SetFixup(fixup);
241 return result;
242 }
243
244 static Address ofConstPool(Assembler *Asm, const Constant *Imm);
245
246 private:
247 Address() {} // Needed by Address::Absolute.
248 };
249
250 class Label {
251 Label(const Label &) = delete;
252 Label &operator=(const Label &) = delete;
253
254 public:
255 Label() : position_(0), num_unresolved_(0) {
256 #ifndef NDEBUG
257 for (int i = 0; i < kMaxUnresolvedBranches; i++) {
258 unresolved_near_positions_[i] = -1;
259 }
260 #endif // !NDEBUG
261 }
262
263 ~Label() {}
264
265 void FinalCheck() const {
266 // Assert if label is being destroyed with unresolved branches pending.
267 assert(!IsLinked());
268 assert(!HasNear());
269 }
270
271 // TODO(jvoung): why are labels offset by this?
272 static const uint32_t kWordSize = sizeof(uint32_t);
273
274 // Returns the position for bound labels (branches that come after this
275 // are considered backward branches). Cannot be used for unused or linked
276 // labels.
277 intptr_t Position() const {
278 assert(IsBound());
279 return -position_ - kWordSize;
280 }
281
282 // Returns the position of an earlier branch instruction that was linked
283 // to this label (branches that use this are considered forward branches).
284 // The linked instructions form a linked list, of sorts, using the
285 // instruction's displacement field for the location of the next
286 // instruction that is also linked to this label.
287 intptr_t LinkPosition() const {
288 assert(IsLinked());
289 return position_ - kWordSize;
290 }
291
292 // Returns the position of an earlier branch instruction which
293 // assumes that this label is "near", and bumps iterator to the
294 // next near position.
295 intptr_t NearPosition() {
296 assert(HasNear());
297 return unresolved_near_positions_[--num_unresolved_];
298 }
299
300 bool IsBound() const { return position_ < 0; }
301 bool IsLinked() const { return position_ > 0; }
302 bool IsUnused() const { return (position_ == 0) && (num_unresolved_ == 0); }
303 bool HasNear() const { return num_unresolved_ != 0; }
304
305 private:
306 void BindTo(intptr_t position) {
307 assert(!IsBound());
308 assert(!HasNear());
309 position_ = -position - kWordSize;
310 assert(IsBound());
311 }
312
313 void LinkTo(intptr_t position) {
314 assert(!IsBound());
315 position_ = position + kWordSize;
316 assert(IsLinked());
317 }
318
319 void NearLinkTo(intptr_t position) {
320 assert(!IsBound());
321 assert(num_unresolved_ < kMaxUnresolvedBranches);
322 unresolved_near_positions_[num_unresolved_++] = position;
323 }
324
325 static const int kMaxUnresolvedBranches = 20;
326
327 intptr_t position_;
328 intptr_t num_unresolved_;
329 // TODO(stichnot,jvoung): Can this instead be
330 // llvm::SmallVector<intptr_t, kMaxUnresolvedBranches> ?
331 intptr_t unresolved_near_positions_[kMaxUnresolvedBranches];
332
333 friend class AssemblerX8632;
334 };
335
336 class AssemblerX8632 : public Assembler {
337 AssemblerX8632(const AssemblerX8632 &) = delete;
338 AssemblerX8632 &operator=(const AssemblerX8632 &) = delete;
339
340 public:
341 explicit AssemblerX8632(bool use_far_branches = false) : Assembler() {
342 // This mode is only needed and implemented for MIPS and ARM.
343 assert(!use_far_branches);
344 (void)use_far_branches;
345 }
346 ~AssemblerX8632() override;
347
348 static const bool kNearJump = true;
349 static const bool kFarJump = false;
350
351 void alignFunction() override;
352
353 SizeT getBundleAlignLog2Bytes() const override { return 5; }
354
355 const char *getNonExecPadDirective() const override { return ".p2align"; }
356
357 llvm::ArrayRef<uint8_t> getNonExecBundlePadding() const override {
358 static const uint8_t Padding[] = {0xF4};
359 return llvm::ArrayRef<uint8_t>(Padding, 1);
360 }
361
362 void padWithNop(intptr_t Padding) override {
363 while (Padding > MAX_NOP_SIZE) {
364 nop(MAX_NOP_SIZE);
365 Padding -= MAX_NOP_SIZE;
366 }
367 if (Padding)
368 nop(Padding);
369 }
370
371 Label *GetOrCreateCfgNodeLabel(SizeT NodeNumber);
372 void BindCfgNodeLabel(SizeT NodeNumber) override;
373 Label *GetOrCreateLocalLabel(SizeT Number);
374 void BindLocalLabel(SizeT Number);
375
376 bool fixupIsPCRel(FixupKind Kind) const override {
377 // Currently assuming this is the only PC-rel relocation type used.
378 return Kind == llvm::ELF::R_386_PC32;
379 }
380
381 // Operations to emit GPR instructions (and dispatch on operand type).
382 typedef void (AssemblerX8632::*TypedEmitGPR)(Type, GPRRegister);
383 typedef void (AssemblerX8632::*TypedEmitAddr)(Type, const Address &);
384 struct GPREmitterOneOp {
385 TypedEmitGPR Reg;
386 TypedEmitAddr Addr;
387 };
388
389 typedef void (AssemblerX8632::*TypedEmitGPRGPR)(Type, GPRRegister,
390 GPRRegister);
391 typedef void (AssemblerX8632::*TypedEmitGPRAddr)(Type, GPRRegister,
392 const Address &);
393 typedef void (AssemblerX8632::*TypedEmitGPRImm)(Type, GPRRegister,
394 const Immediate &);
395 struct GPREmitterRegOp {
396 TypedEmitGPRGPR GPRGPR;
397 TypedEmitGPRAddr GPRAddr;
398 TypedEmitGPRImm GPRImm;
399 };
400
401 struct GPREmitterShiftOp {
402 // Technically, Addr/GPR and Addr/Imm are also allowed, but */Addr are not.
403 // In practice, we always normalize the Dest to a Register first.
404 TypedEmitGPRGPR GPRGPR;
405 TypedEmitGPRImm GPRImm;
406 };
407
408 typedef void (AssemblerX8632::*TypedEmitGPRGPRImm)(Type, GPRRegister,
409 GPRRegister,
410 const Immediate &);
411 struct GPREmitterShiftD {
412 // Technically AddrGPR and AddrGPRImm are also allowed, but in practice
413 // we always normalize Dest to a Register first.
414 TypedEmitGPRGPR GPRGPR;
415 TypedEmitGPRGPRImm GPRGPRImm;
416 };
417
418 typedef void (AssemblerX8632::*TypedEmitAddrGPR)(Type, const Address &,
419 GPRRegister);
420 typedef void (AssemblerX8632::*TypedEmitAddrImm)(Type, const Address &,
421 const Immediate &);
422 struct GPREmitterAddrOp {
423 TypedEmitAddrGPR AddrGPR;
424 TypedEmitAddrImm AddrImm;
425 };
426
427 // Operations to emit XMM instructions (and dispatch on operand type).
428 typedef void (AssemblerX8632::*TypedEmitXmmXmm)(Type, XmmRegister,
429 XmmRegister);
430 typedef void (AssemblerX8632::*TypedEmitXmmAddr)(Type, XmmRegister,
431 const Address &);
432 struct XmmEmitterRegOp {
433 TypedEmitXmmXmm XmmXmm;
434 TypedEmitXmmAddr XmmAddr;
435 };
436
437 typedef void (AssemblerX8632::*EmitXmmXmm)(XmmRegister, XmmRegister);
438 typedef void (AssemblerX8632::*EmitXmmAddr)(XmmRegister, const Address &);
439 typedef void (AssemblerX8632::*EmitAddrXmm)(const Address &, XmmRegister);
440 struct XmmEmitterMovOps {
441 EmitXmmXmm XmmXmm;
442 EmitXmmAddr XmmAddr;
443 EmitAddrXmm AddrXmm;
444 };
445
446 typedef void (AssemblerX8632::*TypedEmitXmmImm)(Type, XmmRegister,
447 const Immediate &);
448
449 struct XmmEmitterShiftOp {
450 TypedEmitXmmXmm XmmXmm;
451 TypedEmitXmmAddr XmmAddr;
452 TypedEmitXmmImm XmmImm;
453 };
454
455 // Cross Xmm/GPR cast instructions.
456 template <typename DReg_t, typename SReg_t> struct CastEmitterRegOp {
457 typedef void (AssemblerX8632::*TypedEmitRegs)(Type, DReg_t, SReg_t);
458 typedef void (AssemblerX8632::*TypedEmitAddr)(Type, DReg_t,
459 const Address &);
460
461 TypedEmitRegs RegReg;
462 TypedEmitAddr RegAddr;
463 };
464
465 // Three operand (potentially) cross Xmm/GPR instructions.
466 // The last operand must be an immediate.
467 template <typename DReg_t, typename SReg_t> struct ThreeOpImmEmitter {
468 typedef void (AssemblerX8632::*TypedEmitRegRegImm)(Type, DReg_t, SReg_t,
469 const Immediate &);
470 typedef void (AssemblerX8632::*TypedEmitRegAddrImm)(Type, DReg_t,
471 const Address &,
472 const Immediate &);
473
474 TypedEmitRegRegImm RegRegImm;
475 TypedEmitRegAddrImm RegAddrImm;
476 };
477
478 /*
479 * Emit Machine Instructions.
480 */
481 void call(GPRRegister reg);
482 void call(const Address &address);
483 void call(const ConstantRelocatable *label);
484 void call(const Immediate &abs_address);
485
486 static const intptr_t kCallExternalLabelSize = 5;
487
488 void pushl(GPRRegister reg);
489
490 void popl(GPRRegister reg);
491 void popl(const Address &address);
492
493 void pushal();
494 void popal();
495
496 void setcc(CondX86::BrCond condition, ByteRegister dst);
497 void setcc(CondX86::BrCond condition, const Address &address);
498
499 void mov(Type Ty, GPRRegister dst, const Immediate &src);
500 void mov(Type Ty, GPRRegister dst, GPRRegister src);
501
502 void mov(Type Ty, GPRRegister dst, const Address &src);
503 void mov(Type Ty, const Address &dst, GPRRegister src);
504 void mov(Type Ty, const Address &dst, const Immediate &imm);
505
506 void movzx(Type Ty, GPRRegister dst, GPRRegister src);
507 void movzx(Type Ty, GPRRegister dst, const Address &src);
508 void movsx(Type Ty, GPRRegister dst, GPRRegister src);
509 void movsx(Type Ty, GPRRegister dst, const Address &src);
510
511 void lea(Type Ty, GPRRegister dst, const Address &src);
512
513 void cmov(Type Ty, CondX86::BrCond cond, GPRRegister dst, GPRRegister src);
514 void cmov(Type Ty, CondX86::BrCond cond, GPRRegister dst, const Address &src);
515
516 void rep_movsb();
517
518 void movss(Type Ty, XmmRegister dst, const Address &src);
519 void movss(Type Ty, const Address &dst, XmmRegister src);
520 void movss(Type Ty, XmmRegister dst, XmmRegister src);
521
522 void movd(XmmRegister dst, GPRRegister src);
523 void movd(XmmRegister dst, const Address &src);
524 void movd(GPRRegister dst, XmmRegister src);
525 void movd(const Address &dst, XmmRegister src);
526
527 void movq(XmmRegister dst, XmmRegister src);
528 void movq(const Address &dst, XmmRegister src);
529 void movq(XmmRegister dst, const Address &src);
530
531 void addss(Type Ty, XmmRegister dst, XmmRegister src);
532 void addss(Type Ty, XmmRegister dst, const Address &src);
533 void subss(Type Ty, XmmRegister dst, XmmRegister src);
534 void subss(Type Ty, XmmRegister dst, const Address &src);
535 void mulss(Type Ty, XmmRegister dst, XmmRegister src);
536 void mulss(Type Ty, XmmRegister dst, const Address &src);
537 void divss(Type Ty, XmmRegister dst, XmmRegister src);
538 void divss(Type Ty, XmmRegister dst, const Address &src);
539
540 void movaps(XmmRegister dst, XmmRegister src);
541
542 void movups(XmmRegister dst, XmmRegister src);
543 void movups(XmmRegister dst, const Address &src);
544 void movups(const Address &dst, XmmRegister src);
545
546 void padd(Type Ty, XmmRegister dst, XmmRegister src);
547 void padd(Type Ty, XmmRegister dst, const Address &src);
548 void pand(Type Ty, XmmRegister dst, XmmRegister src);
549 void pand(Type Ty, XmmRegister dst, const Address &src);
550 void pandn(Type Ty, XmmRegister dst, XmmRegister src);
551 void pandn(Type Ty, XmmRegister dst, const Address &src);
552 void pmull(Type Ty, XmmRegister dst, XmmRegister src);
553 void pmull(Type Ty, XmmRegister dst, const Address &src);
554 void pmuludq(Type Ty, XmmRegister dst, XmmRegister src);
555 void pmuludq(Type Ty, XmmRegister dst, const Address &src);
556 void por(Type Ty, XmmRegister dst, XmmRegister src);
557 void por(Type Ty, XmmRegister dst, const Address &src);
558 void psub(Type Ty, XmmRegister dst, XmmRegister src);
559 void psub(Type Ty, XmmRegister dst, const Address &src);
560 void pxor(Type Ty, XmmRegister dst, XmmRegister src);
561 void pxor(Type Ty, XmmRegister dst, const Address &src);
562
563 void psll(Type Ty, XmmRegister dst, XmmRegister src);
564 void psll(Type Ty, XmmRegister dst, const Address &src);
565 void psll(Type Ty, XmmRegister dst, const Immediate &src);
566
567 void psra(Type Ty, XmmRegister dst, XmmRegister src);
568 void psra(Type Ty, XmmRegister dst, const Address &src);
569 void psra(Type Ty, XmmRegister dst, const Immediate &src);
570 void psrl(Type Ty, XmmRegister dst, XmmRegister src);
571 void psrl(Type Ty, XmmRegister dst, const Address &src);
572 void psrl(Type Ty, XmmRegister dst, const Immediate &src);
573
574 void addps(Type Ty, XmmRegister dst, XmmRegister src);
575 void addps(Type Ty, XmmRegister dst, const Address &src);
576 void subps(Type Ty, XmmRegister dst, XmmRegister src);
577 void subps(Type Ty, XmmRegister dst, const Address &src);
578 void divps(Type Ty, XmmRegister dst, XmmRegister src);
579 void divps(Type Ty, XmmRegister dst, const Address &src);
580 void mulps(Type Ty, XmmRegister dst, XmmRegister src);
581 void mulps(Type Ty, XmmRegister dst, const Address &src);
582 void minps(XmmRegister dst, XmmRegister src);
583 void maxps(XmmRegister dst, XmmRegister src);
584 void andps(XmmRegister dst, XmmRegister src);
585 void andps(XmmRegister dst, const Address &src);
586 void orps(XmmRegister dst, XmmRegister src);
587
588 void blendvps(Type Ty, XmmRegister dst, XmmRegister src);
589 void blendvps(Type Ty, XmmRegister dst, const Address &src);
590 void pblendvb(Type Ty, XmmRegister dst, XmmRegister src);
591 void pblendvb(Type Ty, XmmRegister dst, const Address &src);
592
593 void cmpps(XmmRegister dst, XmmRegister src, CondX86::CmppsCond CmpCondition);
594 void cmpps(XmmRegister dst, const Address &src,
595 CondX86::CmppsCond CmpCondition);
596
597 void sqrtps(XmmRegister dst);
598 void rsqrtps(XmmRegister dst);
599 void reciprocalps(XmmRegister dst);
600 void movhlps(XmmRegister dst, XmmRegister src);
601 void movlhps(XmmRegister dst, XmmRegister src);
602 void unpcklps(XmmRegister dst, XmmRegister src);
603 void unpckhps(XmmRegister dst, XmmRegister src);
604 void unpcklpd(XmmRegister dst, XmmRegister src);
605 void unpckhpd(XmmRegister dst, XmmRegister src);
606
607 void set1ps(XmmRegister dst, GPRRegister tmp, const Immediate &imm);
608 void shufps(XmmRegister dst, XmmRegister src, const Immediate &mask);
609
610 void minpd(XmmRegister dst, XmmRegister src);
611 void maxpd(XmmRegister dst, XmmRegister src);
612 void sqrtpd(XmmRegister dst);
613 void shufpd(XmmRegister dst, XmmRegister src, const Immediate &mask);
614
615 void pshufd(Type Ty, XmmRegister dst, XmmRegister src, const Immediate &mask);
616 void pshufd(Type Ty, XmmRegister dst, const Address &src,
617 const Immediate &mask);
618 void shufps(Type Ty, XmmRegister dst, XmmRegister src, const Immediate &mask);
619 void shufps(Type Ty, XmmRegister dst, const Address &src,
620 const Immediate &mask);
621
622 void cvtdq2ps(Type, XmmRegister dst, XmmRegister src);
623 void cvtdq2ps(Type, XmmRegister dst, const Address &src);
624
625 void cvttps2dq(Type, XmmRegister dst, XmmRegister src);
626 void cvttps2dq(Type, XmmRegister dst, const Address &src);
627
628 void cvtsi2ss(Type DestTy, XmmRegister dst, GPRRegister src);
629 void cvtsi2ss(Type DestTy, XmmRegister dst, const Address &src);
630
631 void cvtfloat2float(Type SrcTy, XmmRegister dst, XmmRegister src);
632 void cvtfloat2float(Type SrcTy, XmmRegister dst, const Address &src);
633
634 void cvttss2si(Type SrcTy, GPRRegister dst, XmmRegister src);
635 void cvttss2si(Type SrcTy, GPRRegister dst, const Address &src);
636
637 void ucomiss(Type Ty, XmmRegister a, XmmRegister b);
638 void ucomiss(Type Ty, XmmRegister a, const Address &b);
639
640 void movmskpd(GPRRegister dst, XmmRegister src);
641 void movmskps(GPRRegister dst, XmmRegister src);
642
643 void sqrtss(Type Ty, XmmRegister dst, const Address &src);
644 void sqrtss(Type Ty, XmmRegister dst, XmmRegister src);
645
646 void xorpd(XmmRegister dst, const Address &src);
647 void xorpd(XmmRegister dst, XmmRegister src);
648 void xorps(XmmRegister dst, const Address &src);
649 void xorps(XmmRegister dst, XmmRegister src);
650
651 void andpd(XmmRegister dst, const Address &src);
652 void andpd(XmmRegister dst, XmmRegister src);
653
654 void orpd(XmmRegister dst, XmmRegister src);
655
656 void insertps(Type Ty, XmmRegister dst, XmmRegister src,
657 const Immediate &imm);
658 void insertps(Type Ty, XmmRegister dst, const Address &src,
659 const Immediate &imm);
660
661 void pinsr(Type Ty, XmmRegister dst, GPRRegister src, const Immediate &imm);
662 void pinsr(Type Ty, XmmRegister dst, const Address &src,
663 const Immediate &imm);
664
665 void pextr(Type Ty, GPRRegister dst, XmmRegister src, const Immediate &imm);
666 void pextr(Type Ty, GPRRegister dst, const Address &src,
667 const Immediate &imm);
668
669 void pmovsxdq(XmmRegister dst, XmmRegister src);
670
671 void pcmpeq(Type Ty, XmmRegister dst, XmmRegister src);
672 void pcmpeq(Type Ty, XmmRegister dst, const Address &src);
673 void pcmpgt(Type Ty, XmmRegister dst, XmmRegister src);
674 void pcmpgt(Type Ty, XmmRegister dst, const Address &src);
675
676 enum RoundingMode {
677 kRoundToNearest = 0x0,
678 kRoundDown = 0x1,
679 kRoundUp = 0x2,
680 kRoundToZero = 0x3
681 };
682 void roundsd(XmmRegister dst, XmmRegister src, RoundingMode mode);
683
684 void fld(Type Ty, const Address &src);
685 void fstp(Type Ty, const Address &dst);
686 void fstp(X87STRegister st);
687
688 void fnstcw(const Address &dst);
689 void fldcw(const Address &src);
690
691 void fistpl(const Address &dst);
692 void fistps(const Address &dst);
693 void fildl(const Address &src);
694 void filds(const Address &src);
695
696 void fincstp();
697
698 void cmp(Type Ty, GPRRegister reg0, GPRRegister reg1);
699 void cmp(Type Ty, GPRRegister reg, const Address &address);
700 void cmp(Type Ty, GPRRegister reg, const Immediate &imm);
701 void cmp(Type Ty, const Address &address, GPRRegister reg);
702 void cmp(Type Ty, const Address &address, const Immediate &imm);
703
704 void test(Type Ty, GPRRegister reg0, GPRRegister reg1);
705 void test(Type Ty, GPRRegister reg, const Immediate &imm);
706 void test(Type Ty, const Address &address, GPRRegister reg);
707 void test(Type Ty, const Address &address, const Immediate &imm);
708
709 void And(Type Ty, GPRRegister dst, GPRRegister src);
710 void And(Type Ty, GPRRegister dst, const Address &address);
711 void And(Type Ty, GPRRegister dst, const Immediate &imm);
712
713 void Or(Type Ty, GPRRegister dst, GPRRegister src);
714 void Or(Type Ty, GPRRegister dst, const Address &address);
715 void Or(Type Ty, GPRRegister dst, const Immediate &imm);
716
717 void Xor(Type Ty, GPRRegister dst, GPRRegister src);
718 void Xor(Type Ty, GPRRegister dst, const Address &address);
719 void Xor(Type Ty, GPRRegister dst, const Immediate &imm);
720
721 void add(Type Ty, GPRRegister dst, GPRRegister src);
722 void add(Type Ty, GPRRegister reg, const Address &address);
723 void add(Type Ty, GPRRegister reg, const Immediate &imm);
724
725 void adc(Type Ty, GPRRegister dst, GPRRegister src);
726 void adc(Type Ty, GPRRegister dst, const Address &address);
727 void adc(Type Ty, GPRRegister reg, const Immediate &imm);
728
729 void sub(Type Ty, GPRRegister dst, GPRRegister src);
730 void sub(Type Ty, GPRRegister reg, const Address &address);
731 void sub(Type Ty, GPRRegister reg, const Immediate &imm);
732
733 void sbb(Type Ty, GPRRegister dst, GPRRegister src);
734 void sbb(Type Ty, GPRRegister reg, const Address &address);
735 void sbb(Type Ty, GPRRegister reg, const Immediate &imm);
736
737 void cbw();
738 void cwd();
739 void cdq();
740
741 void div(Type Ty, GPRRegister reg);
742 void div(Type Ty, const Address &address);
743
744 void idiv(Type Ty, GPRRegister reg);
745 void idiv(Type Ty, const Address &address);
746
747 void imul(Type Ty, GPRRegister dst, GPRRegister src);
748 void imul(Type Ty, GPRRegister reg, const Immediate &imm);
749 void imul(Type Ty, GPRRegister reg, const Address &address);
750
751 void imul(Type Ty, GPRRegister reg);
752 void imul(Type Ty, const Address &address);
753
754 void mul(Type Ty, GPRRegister reg);
755 void mul(Type Ty, const Address &address);
756
757 void incl(GPRRegister reg);
758 void incl(const Address &address);
759
760 void decl(GPRRegister reg);
761 void decl(const Address &address);
762
763 void rol(Type Ty, GPRRegister reg, const Immediate &imm);
764 void rol(Type Ty, GPRRegister operand, GPRRegister shifter);
765 void rol(Type Ty, const Address &operand, GPRRegister shifter);
766
767 void shl(Type Ty, GPRRegister reg, const Immediate &imm);
768 void shl(Type Ty, GPRRegister operand, GPRRegister shifter);
769 void shl(Type Ty, const Address &operand, GPRRegister shifter);
770
771 void shr(Type Ty, GPRRegister reg, const Immediate &imm);
772 void shr(Type Ty, GPRRegister operand, GPRRegister shifter);
773 void shr(Type Ty, const Address &operand, GPRRegister shifter);
774
775 void sar(Type Ty, GPRRegister reg, const Immediate &imm);
776 void sar(Type Ty, GPRRegister operand, GPRRegister shifter);
777 void sar(Type Ty, const Address &address, GPRRegister shifter);
778
779 void shld(Type Ty, GPRRegister dst, GPRRegister src);
780 void shld(Type Ty, GPRRegister dst, GPRRegister src, const Immediate &imm);
781 void shld(Type Ty, const Address &operand, GPRRegister src);
782 void shrd(Type Ty, GPRRegister dst, GPRRegister src);
783 void shrd(Type Ty, GPRRegister dst, GPRRegister src, const Immediate &imm);
784 void shrd(Type Ty, const Address &dst, GPRRegister src);
785
786 void neg(Type Ty, GPRRegister reg);
787 void neg(Type Ty, const Address &addr);
788 void notl(GPRRegister reg);
789
790 void bsf(Type Ty, GPRRegister dst, GPRRegister src);
791 void bsf(Type Ty, GPRRegister dst, const Address &src);
792 void bsr(Type Ty, GPRRegister dst, GPRRegister src);
793 void bsr(Type Ty, GPRRegister dst, const Address &src);
794
795 void bswap(Type Ty, GPRRegister reg);
796
797 void bt(GPRRegister base, GPRRegister offset);
798
799 void ret();
800 void ret(const Immediate &imm);
801
802 // 'size' indicates size in bytes and must be in the range 1..8.
803 void nop(int size = 1);
804 void int3();
805 void hlt();
806 void ud2();
807
808 void j(CondX86::BrCond condition, Label *label, bool near = kFarJump);
809 void j(CondX86::BrCond condition, const ConstantRelocatable *label);
810
811 void jmp(GPRRegister reg);
812 void jmp(Label *label, bool near = kFarJump);
813 void jmp(const ConstantRelocatable *label);
814
815 void mfence();
816
817 void lock();
818 void cmpxchg(Type Ty, const Address &address, GPRRegister reg, bool Locked);
819 void cmpxchg8b(const Address &address, bool Locked);
820 void xadd(Type Ty, const Address &address, GPRRegister reg, bool Locked);
821 void xchg(Type Ty, const Address &address, GPRRegister reg);
822
823 void EmitSegmentOverride(uint8_t prefix);
824
825 intptr_t PreferredLoopAlignment() { return 16; }
826 void Align(intptr_t alignment, intptr_t offset);
827 void Bind(Label *label);
828
829 intptr_t CodeSize() const { return buffer_.Size(); }
830
831 private:
832 inline void EmitUint8(uint8_t value);
833 inline void EmitInt16(int16_t value);
834 inline void EmitInt32(int32_t value);
835 inline void EmitRegisterOperand(int rm, int reg);
836 inline void EmitXmmRegisterOperand(int rm, XmmRegister reg);
837 inline void EmitFixup(AssemblerFixup *fixup);
838 inline void EmitOperandSizeOverride();
839
840 void EmitOperand(int rm, const Operand &operand);
841 void EmitImmediate(Type ty, const Immediate &imm);
842 void EmitComplexI8(int rm, const Operand &operand,
843 const Immediate &immediate);
844 void EmitComplex(Type Ty, int rm, const Operand &operand,
845 const Immediate &immediate);
846 void EmitLabel(Label *label, intptr_t instruction_size);
847 void EmitLabelLink(Label *label);
848 void EmitNearLabelLink(Label *label);
849
850 void EmitGenericShift(int rm, Type Ty, GPRRegister reg, const Immediate &imm);
851 void EmitGenericShift(int rm, Type Ty, const Operand &operand,
852 GPRRegister shifter);
853
854 typedef std::vector<Label *> LabelVector;
855 // A vector of pool-allocated x86 labels for CFG nodes.
856 LabelVector CfgNodeLabels;
857 // A vector of pool-allocated x86 labels for Local labels.
858 LabelVector LocalLabels;
859
860 Label *GetOrCreateLabel(SizeT Number, LabelVector &Labels);
861 };
862
863 inline void AssemblerX8632::EmitUint8(uint8_t value) {
864 buffer_.Emit<uint8_t>(value);
865 }
866
867 inline void AssemblerX8632::EmitInt16(int16_t value) {
868 buffer_.Emit<int16_t>(value);
869 }
870
871 inline void AssemblerX8632::EmitInt32(int32_t value) {
872 buffer_.Emit<int32_t>(value);
873 }
874
875 inline void AssemblerX8632::EmitRegisterOperand(int rm, int reg) {
876 assert(rm >= 0 && rm < 8);
877 buffer_.Emit<uint8_t>(0xC0 + (rm << 3) + reg);
878 }
879
880 inline void AssemblerX8632::EmitXmmRegisterOperand(int rm, XmmRegister reg) {
881 EmitRegisterOperand(rm, static_cast<GPRRegister>(reg));
882 }
883
884 inline void AssemblerX8632::EmitFixup(AssemblerFixup *fixup) {
885 buffer_.EmitFixup(fixup);
886 }
887
888 inline void AssemblerX8632::EmitOperandSizeOverride() { EmitUint8(0x66); }
889
890 } // end of namespace X8632
891 } // end of namespace Ice
892
893 #endif // SUBZERO_SRC_ASSEMBLER_IA32_H
OLDNEW
« no previous file with comments | « src/assembler_arm32.h ('k') | src/assembler_ia32.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698