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