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

Side by Side Diff: src/IceAssemblerX8632.h

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

Powered by Google App Engine
This is Rietveld 408576698