IceTargetLoweringX8632Traits.h revision 5d0acff3a2fa421923392aadb4df2742064b6248
15d0acff3a2fa421923392aadb4df2742064b6248John Porto//===- subzero/src/IceTargetLoweringX8632Traits.h - x86-32 traits -*- C++ -*-=//
25d0acff3a2fa421923392aadb4df2742064b6248John Porto//
35d0acff3a2fa421923392aadb4df2742064b6248John Porto//                        The Subzero Code Generator
45d0acff3a2fa421923392aadb4df2742064b6248John Porto//
55d0acff3a2fa421923392aadb4df2742064b6248John Porto// This file is distributed under the University of Illinois Open Source
65d0acff3a2fa421923392aadb4df2742064b6248John Porto// License. See LICENSE.TXT for details.
75d0acff3a2fa421923392aadb4df2742064b6248John Porto//
85d0acff3a2fa421923392aadb4df2742064b6248John Porto//===----------------------------------------------------------------------===//
95d0acff3a2fa421923392aadb4df2742064b6248John Porto//
105d0acff3a2fa421923392aadb4df2742064b6248John Porto// This file defines the X8632 Target Lowering Traits.
115d0acff3a2fa421923392aadb4df2742064b6248John Porto//
125d0acff3a2fa421923392aadb4df2742064b6248John Porto//===----------------------------------------------------------------------===//
135d0acff3a2fa421923392aadb4df2742064b6248John Porto
145d0acff3a2fa421923392aadb4df2742064b6248John Porto#ifndef SUBZERO_SRC_ICETARGETLOWERINGX8632TRAITS_H
155d0acff3a2fa421923392aadb4df2742064b6248John Porto#define SUBZERO_SRC_ICETARGETLOWERINGX8632TRAITS_H
165d0acff3a2fa421923392aadb4df2742064b6248John Porto
175d0acff3a2fa421923392aadb4df2742064b6248John Porto#include "IceAssembler.h"
185d0acff3a2fa421923392aadb4df2742064b6248John Porto#include "IceConditionCodesX8632.h"
195d0acff3a2fa421923392aadb4df2742064b6248John Porto#include "IceDefs.h"
205d0acff3a2fa421923392aadb4df2742064b6248John Porto#include "IceInst.h"
215d0acff3a2fa421923392aadb4df2742064b6248John Porto#include "IceInstX8632.def"
225d0acff3a2fa421923392aadb4df2742064b6248John Porto#include "IceRegistersX8632.h"
235d0acff3a2fa421923392aadb4df2742064b6248John Porto#include "IceTargetLoweringX8632.def"
245d0acff3a2fa421923392aadb4df2742064b6248John Porto
255d0acff3a2fa421923392aadb4df2742064b6248John Portonamespace Ice {
265d0acff3a2fa421923392aadb4df2742064b6248John Porto
275d0acff3a2fa421923392aadb4df2742064b6248John Portoclass TargetX8632;
285d0acff3a2fa421923392aadb4df2742064b6248John Porto
295d0acff3a2fa421923392aadb4df2742064b6248John Portonamespace X86Internal {
305d0acff3a2fa421923392aadb4df2742064b6248John Porto
315d0acff3a2fa421923392aadb4df2742064b6248John Portotemplate <class Machine> struct MachineTraits;
325d0acff3a2fa421923392aadb4df2742064b6248John Porto
335d0acff3a2fa421923392aadb4df2742064b6248John Portotemplate <> struct MachineTraits<TargetX8632> {
345d0acff3a2fa421923392aadb4df2742064b6248John Porto  //----------------------------------------------------------------------------
355d0acff3a2fa421923392aadb4df2742064b6248John Porto  //     ______  ______  __    __
365d0acff3a2fa421923392aadb4df2742064b6248John Porto  //    /\  __ \/\  ___\/\ "-./  \
375d0acff3a2fa421923392aadb4df2742064b6248John Porto  //    \ \  __ \ \___  \ \ \-./\ \
385d0acff3a2fa421923392aadb4df2742064b6248John Porto  //     \ \_\ \_\/\_____\ \_\ \ \_\
395d0acff3a2fa421923392aadb4df2742064b6248John Porto  //      \/_/\/_/\/_____/\/_/  \/_/
405d0acff3a2fa421923392aadb4df2742064b6248John Porto  //
415d0acff3a2fa421923392aadb4df2742064b6248John Porto  //----------------------------------------------------------------------------
425d0acff3a2fa421923392aadb4df2742064b6248John Porto  enum ScaleFactor { TIMES_1 = 0, TIMES_2 = 1, TIMES_4 = 2, TIMES_8 = 3 };
435d0acff3a2fa421923392aadb4df2742064b6248John Porto
445d0acff3a2fa421923392aadb4df2742064b6248John Porto  using GPRRegister = ::Ice::RegX8632::GPRRegister;
455d0acff3a2fa421923392aadb4df2742064b6248John Porto  using XmmRegister = ::Ice::RegX8632::XmmRegister;
465d0acff3a2fa421923392aadb4df2742064b6248John Porto  using ByteRegister = ::Ice::RegX8632::ByteRegister;
475d0acff3a2fa421923392aadb4df2742064b6248John Porto  using X87STRegister = ::Ice::RegX8632::X87STRegister;
485d0acff3a2fa421923392aadb4df2742064b6248John Porto
495d0acff3a2fa421923392aadb4df2742064b6248John Porto  using Cond = ::Ice::CondX86;
505d0acff3a2fa421923392aadb4df2742064b6248John Porto
515d0acff3a2fa421923392aadb4df2742064b6248John Porto  using RegisterSet = ::Ice::RegX8632;
525d0acff3a2fa421923392aadb4df2742064b6248John Porto  static const GPRRegister Encoded_Reg_Accumulator = RegX8632::Encoded_Reg_eax;
535d0acff3a2fa421923392aadb4df2742064b6248John Porto  static const GPRRegister Encoded_Reg_Counter = RegX8632::Encoded_Reg_ecx;
545d0acff3a2fa421923392aadb4df2742064b6248John Porto  static const FixupKind PcRelFixup = llvm::ELF::R_386_PC32;
555d0acff3a2fa421923392aadb4df2742064b6248John Porto
565d0acff3a2fa421923392aadb4df2742064b6248John Porto  class Operand {
575d0acff3a2fa421923392aadb4df2742064b6248John Porto  public:
585d0acff3a2fa421923392aadb4df2742064b6248John Porto    Operand(const Operand &other)
595d0acff3a2fa421923392aadb4df2742064b6248John Porto        : length_(other.length_), fixup_(other.fixup_) {
605d0acff3a2fa421923392aadb4df2742064b6248John Porto      memmove(&encoding_[0], &other.encoding_[0], other.length_);
615d0acff3a2fa421923392aadb4df2742064b6248John Porto    }
625d0acff3a2fa421923392aadb4df2742064b6248John Porto
635d0acff3a2fa421923392aadb4df2742064b6248John Porto    Operand &operator=(const Operand &other) {
645d0acff3a2fa421923392aadb4df2742064b6248John Porto      length_ = other.length_;
655d0acff3a2fa421923392aadb4df2742064b6248John Porto      fixup_ = other.fixup_;
665d0acff3a2fa421923392aadb4df2742064b6248John Porto      memmove(&encoding_[0], &other.encoding_[0], other.length_);
675d0acff3a2fa421923392aadb4df2742064b6248John Porto      return *this;
685d0acff3a2fa421923392aadb4df2742064b6248John Porto    }
695d0acff3a2fa421923392aadb4df2742064b6248John Porto
705d0acff3a2fa421923392aadb4df2742064b6248John Porto    uint8_t mod() const { return (encoding_at(0) >> 6) & 3; }
715d0acff3a2fa421923392aadb4df2742064b6248John Porto
725d0acff3a2fa421923392aadb4df2742064b6248John Porto    GPRRegister rm() const {
735d0acff3a2fa421923392aadb4df2742064b6248John Porto      return static_cast<GPRRegister>(encoding_at(0) & 7);
745d0acff3a2fa421923392aadb4df2742064b6248John Porto    }
755d0acff3a2fa421923392aadb4df2742064b6248John Porto
765d0acff3a2fa421923392aadb4df2742064b6248John Porto    ScaleFactor scale() const {
775d0acff3a2fa421923392aadb4df2742064b6248John Porto      return static_cast<ScaleFactor>((encoding_at(1) >> 6) & 3);
785d0acff3a2fa421923392aadb4df2742064b6248John Porto    }
795d0acff3a2fa421923392aadb4df2742064b6248John Porto
805d0acff3a2fa421923392aadb4df2742064b6248John Porto    GPRRegister index() const {
815d0acff3a2fa421923392aadb4df2742064b6248John Porto      return static_cast<GPRRegister>((encoding_at(1) >> 3) & 7);
825d0acff3a2fa421923392aadb4df2742064b6248John Porto    }
835d0acff3a2fa421923392aadb4df2742064b6248John Porto
845d0acff3a2fa421923392aadb4df2742064b6248John Porto    GPRRegister base() const {
855d0acff3a2fa421923392aadb4df2742064b6248John Porto      return static_cast<GPRRegister>(encoding_at(1) & 7);
865d0acff3a2fa421923392aadb4df2742064b6248John Porto    }
875d0acff3a2fa421923392aadb4df2742064b6248John Porto
885d0acff3a2fa421923392aadb4df2742064b6248John Porto    int8_t disp8() const {
895d0acff3a2fa421923392aadb4df2742064b6248John Porto      assert(length_ >= 2);
905d0acff3a2fa421923392aadb4df2742064b6248John Porto      return static_cast<int8_t>(encoding_[length_ - 1]);
915d0acff3a2fa421923392aadb4df2742064b6248John Porto    }
925d0acff3a2fa421923392aadb4df2742064b6248John Porto
935d0acff3a2fa421923392aadb4df2742064b6248John Porto    int32_t disp32() const {
945d0acff3a2fa421923392aadb4df2742064b6248John Porto      assert(length_ >= 5);
955d0acff3a2fa421923392aadb4df2742064b6248John Porto      return bit_copy<int32_t>(encoding_[length_ - 4]);
965d0acff3a2fa421923392aadb4df2742064b6248John Porto    }
975d0acff3a2fa421923392aadb4df2742064b6248John Porto
985d0acff3a2fa421923392aadb4df2742064b6248John Porto    AssemblerFixup *fixup() const { return fixup_; }
995d0acff3a2fa421923392aadb4df2742064b6248John Porto
1005d0acff3a2fa421923392aadb4df2742064b6248John Porto  protected:
1015d0acff3a2fa421923392aadb4df2742064b6248John Porto    Operand() : length_(0), fixup_(nullptr) {} // Needed by subclass Address.
1025d0acff3a2fa421923392aadb4df2742064b6248John Porto
1035d0acff3a2fa421923392aadb4df2742064b6248John Porto    void SetModRM(int mod, GPRRegister rm) {
1045d0acff3a2fa421923392aadb4df2742064b6248John Porto      assert((mod & ~3) == 0);
1055d0acff3a2fa421923392aadb4df2742064b6248John Porto      encoding_[0] = (mod << 6) | rm;
1065d0acff3a2fa421923392aadb4df2742064b6248John Porto      length_ = 1;
1075d0acff3a2fa421923392aadb4df2742064b6248John Porto    }
1085d0acff3a2fa421923392aadb4df2742064b6248John Porto
1095d0acff3a2fa421923392aadb4df2742064b6248John Porto    void SetSIB(ScaleFactor scale, GPRRegister index, GPRRegister base) {
1105d0acff3a2fa421923392aadb4df2742064b6248John Porto      assert(length_ == 1);
1115d0acff3a2fa421923392aadb4df2742064b6248John Porto      assert((scale & ~3) == 0);
1125d0acff3a2fa421923392aadb4df2742064b6248John Porto      encoding_[1] = (scale << 6) | (index << 3) | base;
1135d0acff3a2fa421923392aadb4df2742064b6248John Porto      length_ = 2;
1145d0acff3a2fa421923392aadb4df2742064b6248John Porto    }
1155d0acff3a2fa421923392aadb4df2742064b6248John Porto
1165d0acff3a2fa421923392aadb4df2742064b6248John Porto    void SetDisp8(int8_t disp) {
1175d0acff3a2fa421923392aadb4df2742064b6248John Porto      assert(length_ == 1 || length_ == 2);
1185d0acff3a2fa421923392aadb4df2742064b6248John Porto      encoding_[length_++] = static_cast<uint8_t>(disp);
1195d0acff3a2fa421923392aadb4df2742064b6248John Porto    }
1205d0acff3a2fa421923392aadb4df2742064b6248John Porto
1215d0acff3a2fa421923392aadb4df2742064b6248John Porto    void SetDisp32(int32_t disp) {
1225d0acff3a2fa421923392aadb4df2742064b6248John Porto      assert(length_ == 1 || length_ == 2);
1235d0acff3a2fa421923392aadb4df2742064b6248John Porto      intptr_t disp_size = sizeof(disp);
1245d0acff3a2fa421923392aadb4df2742064b6248John Porto      memmove(&encoding_[length_], &disp, disp_size);
1255d0acff3a2fa421923392aadb4df2742064b6248John Porto      length_ += disp_size;
1265d0acff3a2fa421923392aadb4df2742064b6248John Porto    }
1275d0acff3a2fa421923392aadb4df2742064b6248John Porto
1285d0acff3a2fa421923392aadb4df2742064b6248John Porto    void SetFixup(AssemblerFixup *fixup) { fixup_ = fixup; }
1295d0acff3a2fa421923392aadb4df2742064b6248John Porto
1305d0acff3a2fa421923392aadb4df2742064b6248John Porto  private:
1315d0acff3a2fa421923392aadb4df2742064b6248John Porto    uint8_t length_;
1325d0acff3a2fa421923392aadb4df2742064b6248John Porto    uint8_t encoding_[6];
1335d0acff3a2fa421923392aadb4df2742064b6248John Porto    AssemblerFixup *fixup_;
1345d0acff3a2fa421923392aadb4df2742064b6248John Porto
1355d0acff3a2fa421923392aadb4df2742064b6248John Porto    explicit Operand(GPRRegister reg) : fixup_(nullptr) { SetModRM(3, reg); }
1365d0acff3a2fa421923392aadb4df2742064b6248John Porto
1375d0acff3a2fa421923392aadb4df2742064b6248John Porto    // Get the operand encoding byte at the given index.
1385d0acff3a2fa421923392aadb4df2742064b6248John Porto    uint8_t encoding_at(intptr_t index) const {
1395d0acff3a2fa421923392aadb4df2742064b6248John Porto      assert(index >= 0 && index < length_);
1405d0acff3a2fa421923392aadb4df2742064b6248John Porto      return encoding_[index];
1415d0acff3a2fa421923392aadb4df2742064b6248John Porto    }
1425d0acff3a2fa421923392aadb4df2742064b6248John Porto
1435d0acff3a2fa421923392aadb4df2742064b6248John Porto    // Returns whether or not this operand is really the given register in
1445d0acff3a2fa421923392aadb4df2742064b6248John Porto    // disguise. Used from the assembler to generate better encodings.
1455d0acff3a2fa421923392aadb4df2742064b6248John Porto    bool IsRegister(GPRRegister reg) const {
1465d0acff3a2fa421923392aadb4df2742064b6248John Porto      return ((encoding_[0] & 0xF8) ==
1475d0acff3a2fa421923392aadb4df2742064b6248John Porto              0xC0) // Addressing mode is register only.
1485d0acff3a2fa421923392aadb4df2742064b6248John Porto             &&
1495d0acff3a2fa421923392aadb4df2742064b6248John Porto             ((encoding_[0] & 0x07) == reg); // Register codes match.
1505d0acff3a2fa421923392aadb4df2742064b6248John Porto    }
1515d0acff3a2fa421923392aadb4df2742064b6248John Porto
1525d0acff3a2fa421923392aadb4df2742064b6248John Porto    template <class> friend class AssemblerX86Base;
1535d0acff3a2fa421923392aadb4df2742064b6248John Porto  };
1545d0acff3a2fa421923392aadb4df2742064b6248John Porto
1555d0acff3a2fa421923392aadb4df2742064b6248John Porto  class Address : public Operand {
1565d0acff3a2fa421923392aadb4df2742064b6248John Porto    Address() = delete;
1575d0acff3a2fa421923392aadb4df2742064b6248John Porto
1585d0acff3a2fa421923392aadb4df2742064b6248John Porto  public:
1595d0acff3a2fa421923392aadb4df2742064b6248John Porto    Address(const Address &other) : Operand(other) {}
1605d0acff3a2fa421923392aadb4df2742064b6248John Porto
1615d0acff3a2fa421923392aadb4df2742064b6248John Porto    Address &operator=(const Address &other) {
1625d0acff3a2fa421923392aadb4df2742064b6248John Porto      Operand::operator=(other);
1635d0acff3a2fa421923392aadb4df2742064b6248John Porto      return *this;
1645d0acff3a2fa421923392aadb4df2742064b6248John Porto    }
1655d0acff3a2fa421923392aadb4df2742064b6248John Porto
1665d0acff3a2fa421923392aadb4df2742064b6248John Porto    Address(GPRRegister base, int32_t disp) {
1675d0acff3a2fa421923392aadb4df2742064b6248John Porto      if (disp == 0 && base != RegX8632::Encoded_Reg_ebp) {
1685d0acff3a2fa421923392aadb4df2742064b6248John Porto        SetModRM(0, base);
1695d0acff3a2fa421923392aadb4df2742064b6248John Porto        if (base == RegX8632::Encoded_Reg_esp)
1705d0acff3a2fa421923392aadb4df2742064b6248John Porto          SetSIB(TIMES_1, RegX8632::Encoded_Reg_esp, base);
1715d0acff3a2fa421923392aadb4df2742064b6248John Porto      } else if (Utils::IsInt(8, disp)) {
1725d0acff3a2fa421923392aadb4df2742064b6248John Porto        SetModRM(1, base);
1735d0acff3a2fa421923392aadb4df2742064b6248John Porto        if (base == RegX8632::Encoded_Reg_esp)
1745d0acff3a2fa421923392aadb4df2742064b6248John Porto          SetSIB(TIMES_1, RegX8632::Encoded_Reg_esp, base);
1755d0acff3a2fa421923392aadb4df2742064b6248John Porto        SetDisp8(disp);
1765d0acff3a2fa421923392aadb4df2742064b6248John Porto      } else {
1775d0acff3a2fa421923392aadb4df2742064b6248John Porto        SetModRM(2, base);
1785d0acff3a2fa421923392aadb4df2742064b6248John Porto        if (base == RegX8632::Encoded_Reg_esp)
1795d0acff3a2fa421923392aadb4df2742064b6248John Porto          SetSIB(TIMES_1, RegX8632::Encoded_Reg_esp, base);
1805d0acff3a2fa421923392aadb4df2742064b6248John Porto        SetDisp32(disp);
1815d0acff3a2fa421923392aadb4df2742064b6248John Porto      }
1825d0acff3a2fa421923392aadb4df2742064b6248John Porto    }
1835d0acff3a2fa421923392aadb4df2742064b6248John Porto
1845d0acff3a2fa421923392aadb4df2742064b6248John Porto    Address(GPRRegister index, ScaleFactor scale, int32_t disp) {
1855d0acff3a2fa421923392aadb4df2742064b6248John Porto      assert(index != RegX8632::Encoded_Reg_esp); // Illegal addressing mode.
1865d0acff3a2fa421923392aadb4df2742064b6248John Porto      SetModRM(0, RegX8632::Encoded_Reg_esp);
1875d0acff3a2fa421923392aadb4df2742064b6248John Porto      SetSIB(scale, index, RegX8632::Encoded_Reg_ebp);
1885d0acff3a2fa421923392aadb4df2742064b6248John Porto      SetDisp32(disp);
1895d0acff3a2fa421923392aadb4df2742064b6248John Porto    }
1905d0acff3a2fa421923392aadb4df2742064b6248John Porto
1915d0acff3a2fa421923392aadb4df2742064b6248John Porto    Address(GPRRegister base, GPRRegister index, ScaleFactor scale,
1925d0acff3a2fa421923392aadb4df2742064b6248John Porto            int32_t disp) {
1935d0acff3a2fa421923392aadb4df2742064b6248John Porto      assert(index != RegX8632::Encoded_Reg_esp); // Illegal addressing mode.
1945d0acff3a2fa421923392aadb4df2742064b6248John Porto      if (disp == 0 && base != RegX8632::Encoded_Reg_ebp) {
1955d0acff3a2fa421923392aadb4df2742064b6248John Porto        SetModRM(0, RegX8632::Encoded_Reg_esp);
1965d0acff3a2fa421923392aadb4df2742064b6248John Porto        SetSIB(scale, index, base);
1975d0acff3a2fa421923392aadb4df2742064b6248John Porto      } else if (Utils::IsInt(8, disp)) {
1985d0acff3a2fa421923392aadb4df2742064b6248John Porto        SetModRM(1, RegX8632::Encoded_Reg_esp);
1995d0acff3a2fa421923392aadb4df2742064b6248John Porto        SetSIB(scale, index, base);
2005d0acff3a2fa421923392aadb4df2742064b6248John Porto        SetDisp8(disp);
2015d0acff3a2fa421923392aadb4df2742064b6248John Porto      } else {
2025d0acff3a2fa421923392aadb4df2742064b6248John Porto        SetModRM(2, RegX8632::Encoded_Reg_esp);
2035d0acff3a2fa421923392aadb4df2742064b6248John Porto        SetSIB(scale, index, base);
2045d0acff3a2fa421923392aadb4df2742064b6248John Porto        SetDisp32(disp);
2055d0acff3a2fa421923392aadb4df2742064b6248John Porto      }
2065d0acff3a2fa421923392aadb4df2742064b6248John Porto    }
2075d0acff3a2fa421923392aadb4df2742064b6248John Porto
2085d0acff3a2fa421923392aadb4df2742064b6248John Porto    // AbsoluteTag is a special tag used by clients to create an absolute
2095d0acff3a2fa421923392aadb4df2742064b6248John Porto    // Address.
2105d0acff3a2fa421923392aadb4df2742064b6248John Porto    enum AbsoluteTag { ABSOLUTE };
2115d0acff3a2fa421923392aadb4df2742064b6248John Porto
2125d0acff3a2fa421923392aadb4df2742064b6248John Porto    Address(AbsoluteTag, const uintptr_t Addr) {
2135d0acff3a2fa421923392aadb4df2742064b6248John Porto      SetModRM(0, RegX8632::Encoded_Reg_ebp);
2145d0acff3a2fa421923392aadb4df2742064b6248John Porto      SetDisp32(Addr);
2155d0acff3a2fa421923392aadb4df2742064b6248John Porto    }
2165d0acff3a2fa421923392aadb4df2742064b6248John Porto
2175d0acff3a2fa421923392aadb4df2742064b6248John Porto    // TODO(jpp): remove this.
2185d0acff3a2fa421923392aadb4df2742064b6248John Porto    static Address Absolute(const uintptr_t Addr) {
2195d0acff3a2fa421923392aadb4df2742064b6248John Porto      return Address(ABSOLUTE, Addr);
2205d0acff3a2fa421923392aadb4df2742064b6248John Porto    }
2215d0acff3a2fa421923392aadb4df2742064b6248John Porto
2225d0acff3a2fa421923392aadb4df2742064b6248John Porto    Address(AbsoluteTag, RelocOffsetT Offset, AssemblerFixup *Fixup) {
2235d0acff3a2fa421923392aadb4df2742064b6248John Porto      SetModRM(0, RegX8632::Encoded_Reg_ebp);
2245d0acff3a2fa421923392aadb4df2742064b6248John Porto      // Use the Offset in the displacement for now. If we decide to process
2255d0acff3a2fa421923392aadb4df2742064b6248John Porto      // fixups later, we'll need to patch up the emitted displacement.
2265d0acff3a2fa421923392aadb4df2742064b6248John Porto      SetDisp32(Offset);
2275d0acff3a2fa421923392aadb4df2742064b6248John Porto      SetFixup(Fixup);
2285d0acff3a2fa421923392aadb4df2742064b6248John Porto    }
2295d0acff3a2fa421923392aadb4df2742064b6248John Porto
2305d0acff3a2fa421923392aadb4df2742064b6248John Porto    // TODO(jpp): remove this.
2315d0acff3a2fa421923392aadb4df2742064b6248John Porto    static Address Absolute(RelocOffsetT Offset, AssemblerFixup *Fixup) {
2325d0acff3a2fa421923392aadb4df2742064b6248John Porto      return Address(ABSOLUTE, Offset, Fixup);
2335d0acff3a2fa421923392aadb4df2742064b6248John Porto    }
2345d0acff3a2fa421923392aadb4df2742064b6248John Porto
2355d0acff3a2fa421923392aadb4df2742064b6248John Porto    static Address ofConstPool(Assembler *Asm, const Constant *Imm) {
2365d0acff3a2fa421923392aadb4df2742064b6248John Porto      AssemblerFixup *Fixup = Asm->createFixup(llvm::ELF::R_386_32, Imm);
2375d0acff3a2fa421923392aadb4df2742064b6248John Porto      const RelocOffsetT Offset = 0;
2385d0acff3a2fa421923392aadb4df2742064b6248John Porto      return Address(ABSOLUTE, Offset, Fixup);
2395d0acff3a2fa421923392aadb4df2742064b6248John Porto    }
2405d0acff3a2fa421923392aadb4df2742064b6248John Porto  };
2415d0acff3a2fa421923392aadb4df2742064b6248John Porto
2425d0acff3a2fa421923392aadb4df2742064b6248John Porto  //----------------------------------------------------------------------------
2435d0acff3a2fa421923392aadb4df2742064b6248John Porto  //     __      ______  __     __  ______  ______  __  __   __  ______
2445d0acff3a2fa421923392aadb4df2742064b6248John Porto  //    /\ \    /\  __ \/\ \  _ \ \/\  ___\/\  == \/\ \/\ "-.\ \/\  ___\
2455d0acff3a2fa421923392aadb4df2742064b6248John Porto  //    \ \ \___\ \ \/\ \ \ \/ ".\ \ \  __\\ \  __<\ \ \ \ \-.  \ \ \__ \
2465d0acff3a2fa421923392aadb4df2742064b6248John Porto  //     \ \_____\ \_____\ \__/".~\_\ \_____\ \_\ \_\ \_\ \_\\"\_\ \_____\
2475d0acff3a2fa421923392aadb4df2742064b6248John Porto  //      \/_____/\/_____/\/_/   \/_/\/_____/\/_/ /_/\/_/\/_/ \/_/\/_____/
2485d0acff3a2fa421923392aadb4df2742064b6248John Porto  //
2495d0acff3a2fa421923392aadb4df2742064b6248John Porto  //----------------------------------------------------------------------------
2505d0acff3a2fa421923392aadb4df2742064b6248John Porto  enum InstructionSet {
2515d0acff3a2fa421923392aadb4df2742064b6248John Porto    Begin,
2525d0acff3a2fa421923392aadb4df2742064b6248John Porto    // SSE2 is the PNaCl baseline instruction set.
2535d0acff3a2fa421923392aadb4df2742064b6248John Porto    SSE2 = Begin,
2545d0acff3a2fa421923392aadb4df2742064b6248John Porto    SSE4_1,
2555d0acff3a2fa421923392aadb4df2742064b6248John Porto    End
2565d0acff3a2fa421923392aadb4df2742064b6248John Porto  };
2575d0acff3a2fa421923392aadb4df2742064b6248John Porto
2585d0acff3a2fa421923392aadb4df2742064b6248John Porto  // The maximum number of arguments to pass in XMM registers
2595d0acff3a2fa421923392aadb4df2742064b6248John Porto  static const uint32_t X86_MAX_XMM_ARGS = 4;
2605d0acff3a2fa421923392aadb4df2742064b6248John Porto  // The number of bits in a byte
2615d0acff3a2fa421923392aadb4df2742064b6248John Porto  static const uint32_t X86_CHAR_BIT = 8;
2625d0acff3a2fa421923392aadb4df2742064b6248John Porto  // Stack alignment. This is defined in IceTargetLoweringX8632.cpp because it
2635d0acff3a2fa421923392aadb4df2742064b6248John Porto  // is used as an argument to std::max(), and the default std::less<T> has an
2645d0acff3a2fa421923392aadb4df2742064b6248John Porto  // operator(T const&, T const&) which requires this member to have an address.
2655d0acff3a2fa421923392aadb4df2742064b6248John Porto  static const uint32_t X86_STACK_ALIGNMENT_BYTES;
2665d0acff3a2fa421923392aadb4df2742064b6248John Porto  // Size of the return address on the stack
2675d0acff3a2fa421923392aadb4df2742064b6248John Porto  static const uint32_t X86_RET_IP_SIZE_BYTES = 4;
2685d0acff3a2fa421923392aadb4df2742064b6248John Porto  // The number of different NOP instructions
2695d0acff3a2fa421923392aadb4df2742064b6248John Porto  static const uint32_t X86_NUM_NOP_VARIANTS = 5;
2705d0acff3a2fa421923392aadb4df2742064b6248John Porto
2715d0acff3a2fa421923392aadb4df2742064b6248John Porto  // Value is in bytes. Return Value adjusted to the next highest multiple
2725d0acff3a2fa421923392aadb4df2742064b6248John Porto  // of the stack alignment.
2735d0acff3a2fa421923392aadb4df2742064b6248John Porto  static uint32_t applyStackAlignment(uint32_t Value) {
2745d0acff3a2fa421923392aadb4df2742064b6248John Porto    return Utils::applyAlignment(Value, X86_STACK_ALIGNMENT_BYTES);
2755d0acff3a2fa421923392aadb4df2742064b6248John Porto  }
2765d0acff3a2fa421923392aadb4df2742064b6248John Porto
2775d0acff3a2fa421923392aadb4df2742064b6248John Porto  // Return the type which the elements of the vector have in the X86
2785d0acff3a2fa421923392aadb4df2742064b6248John Porto  // representation of the vector.
2795d0acff3a2fa421923392aadb4df2742064b6248John Porto  static Type getInVectorElementType(Type Ty) {
2805d0acff3a2fa421923392aadb4df2742064b6248John Porto    assert(isVectorType(Ty));
2815d0acff3a2fa421923392aadb4df2742064b6248John Porto    size_t Index = static_cast<size_t>(Ty);
2825d0acff3a2fa421923392aadb4df2742064b6248John Porto    (void)Index;
2835d0acff3a2fa421923392aadb4df2742064b6248John Porto    assert(Index < TableTypeX8632AttributesSize);
2845d0acff3a2fa421923392aadb4df2742064b6248John Porto    return TableTypeX8632Attributes[Ty].InVectorElementType;
2855d0acff3a2fa421923392aadb4df2742064b6248John Porto  }
2865d0acff3a2fa421923392aadb4df2742064b6248John Porto
2875d0acff3a2fa421923392aadb4df2742064b6248John Porto  // Note: The following data structures are defined in
2885d0acff3a2fa421923392aadb4df2742064b6248John Porto  // IceTargetLoweringX8632.cpp.
2895d0acff3a2fa421923392aadb4df2742064b6248John Porto
2905d0acff3a2fa421923392aadb4df2742064b6248John Porto  // The following table summarizes the logic for lowering the fcmp
2915d0acff3a2fa421923392aadb4df2742064b6248John Porto  // instruction.  There is one table entry for each of the 16 conditions.
2925d0acff3a2fa421923392aadb4df2742064b6248John Porto  //
2935d0acff3a2fa421923392aadb4df2742064b6248John Porto  // The first four columns describe the case when the operands are
2945d0acff3a2fa421923392aadb4df2742064b6248John Porto  // floating point scalar values.  A comment in lowerFcmp() describes the
2955d0acff3a2fa421923392aadb4df2742064b6248John Porto  // lowering template.  In the most general case, there is a compare
2965d0acff3a2fa421923392aadb4df2742064b6248John Porto  // followed by two conditional branches, because some fcmp conditions
2975d0acff3a2fa421923392aadb4df2742064b6248John Porto  // don't map to a single x86 conditional branch.  However, in many cases
2985d0acff3a2fa421923392aadb4df2742064b6248John Porto  // it is possible to swap the operands in the comparison and have a
2995d0acff3a2fa421923392aadb4df2742064b6248John Porto  // single conditional branch.  Since it's quite tedious to validate the
3005d0acff3a2fa421923392aadb4df2742064b6248John Porto  // table by hand, good execution tests are helpful.
3015d0acff3a2fa421923392aadb4df2742064b6248John Porto  //
3025d0acff3a2fa421923392aadb4df2742064b6248John Porto  // The last two columns describe the case when the operands are vectors
3035d0acff3a2fa421923392aadb4df2742064b6248John Porto  // of floating point values.  For most fcmp conditions, there is a clear
3045d0acff3a2fa421923392aadb4df2742064b6248John Porto  // mapping to a single x86 cmpps instruction variant.  Some fcmp
3055d0acff3a2fa421923392aadb4df2742064b6248John Porto  // conditions require special code to handle and these are marked in the
3065d0acff3a2fa421923392aadb4df2742064b6248John Porto  // table with a Cmpps_Invalid predicate.
3075d0acff3a2fa421923392aadb4df2742064b6248John Porto  static const struct TableFcmpType {
3085d0acff3a2fa421923392aadb4df2742064b6248John Porto    uint32_t Default;
3095d0acff3a2fa421923392aadb4df2742064b6248John Porto    bool SwapScalarOperands;
3105d0acff3a2fa421923392aadb4df2742064b6248John Porto    CondX86::BrCond C1, C2;
3115d0acff3a2fa421923392aadb4df2742064b6248John Porto    bool SwapVectorOperands;
3125d0acff3a2fa421923392aadb4df2742064b6248John Porto    CondX86::CmppsCond Predicate;
3135d0acff3a2fa421923392aadb4df2742064b6248John Porto  } TableFcmp[];
3145d0acff3a2fa421923392aadb4df2742064b6248John Porto  static const size_t TableFcmpSize;
3155d0acff3a2fa421923392aadb4df2742064b6248John Porto
3165d0acff3a2fa421923392aadb4df2742064b6248John Porto  // The following table summarizes the logic for lowering the icmp instruction
3175d0acff3a2fa421923392aadb4df2742064b6248John Porto  // for i32 and narrower types.  Each icmp condition has a clear mapping to an
3185d0acff3a2fa421923392aadb4df2742064b6248John Porto  // x86 conditional branch instruction.
3195d0acff3a2fa421923392aadb4df2742064b6248John Porto
3205d0acff3a2fa421923392aadb4df2742064b6248John Porto  static const struct TableIcmp32Type {
3215d0acff3a2fa421923392aadb4df2742064b6248John Porto    CondX86::BrCond Mapping;
3225d0acff3a2fa421923392aadb4df2742064b6248John Porto  } TableIcmp32[];
3235d0acff3a2fa421923392aadb4df2742064b6248John Porto  static const size_t TableIcmp32Size;
3245d0acff3a2fa421923392aadb4df2742064b6248John Porto
3255d0acff3a2fa421923392aadb4df2742064b6248John Porto  // The following table summarizes the logic for lowering the icmp instruction
3265d0acff3a2fa421923392aadb4df2742064b6248John Porto  // for the i64 type.  For Eq and Ne, two separate 32-bit comparisons and
3275d0acff3a2fa421923392aadb4df2742064b6248John Porto  // conditional branches are needed.  For the other conditions, three separate
3285d0acff3a2fa421923392aadb4df2742064b6248John Porto  // conditional branches are needed.
3295d0acff3a2fa421923392aadb4df2742064b6248John Porto  static const struct TableIcmp64Type {
3305d0acff3a2fa421923392aadb4df2742064b6248John Porto    CondX86::BrCond C1, C2, C3;
3315d0acff3a2fa421923392aadb4df2742064b6248John Porto  } TableIcmp64[];
3325d0acff3a2fa421923392aadb4df2742064b6248John Porto  static const size_t TableIcmp64Size;
3335d0acff3a2fa421923392aadb4df2742064b6248John Porto
3345d0acff3a2fa421923392aadb4df2742064b6248John Porto  static CondX86::BrCond getIcmp32Mapping(InstIcmp::ICond Cond) {
3355d0acff3a2fa421923392aadb4df2742064b6248John Porto    size_t Index = static_cast<size_t>(Cond);
3365d0acff3a2fa421923392aadb4df2742064b6248John Porto    assert(Index < TableIcmp32Size);
3375d0acff3a2fa421923392aadb4df2742064b6248John Porto    return TableIcmp32[Index].Mapping;
3385d0acff3a2fa421923392aadb4df2742064b6248John Porto  }
3395d0acff3a2fa421923392aadb4df2742064b6248John Porto
3405d0acff3a2fa421923392aadb4df2742064b6248John Porto  static const struct TableTypeX8632AttributesType {
3415d0acff3a2fa421923392aadb4df2742064b6248John Porto    Type InVectorElementType;
3425d0acff3a2fa421923392aadb4df2742064b6248John Porto  } TableTypeX8632Attributes[];
3435d0acff3a2fa421923392aadb4df2742064b6248John Porto  static const size_t TableTypeX8632AttributesSize;
3445d0acff3a2fa421923392aadb4df2742064b6248John Porto};
3455d0acff3a2fa421923392aadb4df2742064b6248John Porto
3465d0acff3a2fa421923392aadb4df2742064b6248John Porto} // end of namespace X86Internal
3475d0acff3a2fa421923392aadb4df2742064b6248John Porto
3485d0acff3a2fa421923392aadb4df2742064b6248John Portonamespace X8632 {
3495d0acff3a2fa421923392aadb4df2742064b6248John Portousing Traits = ::Ice::X86Internal::MachineTraits<TargetX8632>;
3505d0acff3a2fa421923392aadb4df2742064b6248John Porto} // end of namespace X8632
3515d0acff3a2fa421923392aadb4df2742064b6248John Porto
3525d0acff3a2fa421923392aadb4df2742064b6248John Porto} // end of namespace Ice
3535d0acff3a2fa421923392aadb4df2742064b6248John Porto
3545d0acff3a2fa421923392aadb4df2742064b6248John Porto#endif // SUBZERO_SRC_ICETARGETLOWERINGX8632TRAITS_H
355