| Index: src/IceAssemblerX8664.h
|
| diff --git a/src/IceAssemblerX8664.h b/src/IceAssemblerX8664.h
|
| index f2ffd7f4ee48ede97d9421f2dc5e5894788022e7..358f7afcaff57a9632b9398c3483bf8df19b11f3 100644
|
| --- a/src/IceAssemblerX8664.h
|
| +++ b/src/IceAssemblerX8664.h
|
| @@ -1,4 +1,12 @@
|
| -//===- subzero/src/IceAssemblerX8664.h - Assembler for x86-64 -*- C++ -*---===//
|
| +//===- subzero/src/IceAssemblerX8664.h - Assembler for x86-64 ---*- C++ -*-===//
|
| +//
|
| +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
|
| +// for details. All rights reserved. Use of this source code is governed by a
|
| +// BSD-style license that can be found in the LICENSE file.
|
| +//
|
| +// Modified by the Subzero authors.
|
| +//
|
| +//===----------------------------------------------------------------------===//
|
| //
|
| // The Subzero Code Generator
|
| //
|
| @@ -16,36 +24,106 @@
|
| #define SUBZERO_SRC_ICEASSEMBLERX8664_H
|
|
|
| #include "IceAssembler.h"
|
| +#include "IceAssemblerX86Base.h"
|
| #include "IceDefs.h"
|
| +#include "IceOperand.h"
|
| +#include "IceTargetLoweringX8664Traits.h"
|
| +#include "IceTypes.h"
|
| +#include "IceUtils.h"
|
| +
|
| +#include <type_traits>
|
|
|
| namespace Ice {
|
| +
|
| +class TargetX8664;
|
| +
|
| namespace X8664 {
|
|
|
| -class AssemblerX8664 final : public Assembler {
|
| +using Immediate = ::Ice::X86Internal::Immediate;
|
| +using Label = ::Ice::X86Internal::Label;
|
| +
|
| +class AssemblerX8664 : public X86Internal::AssemblerX86Base<TargetX8664> {
|
| AssemblerX8664(const AssemblerX8664 &) = delete;
|
| AssemblerX8664 &operator=(const AssemblerX8664 &) = delete;
|
|
|
| public:
|
| explicit AssemblerX8664(bool use_far_branches = false)
|
| - : Assembler(Asm_X8664) {
|
| - assert(!use_far_branches);
|
| - (void)use_far_branches;
|
| - llvm::report_fatal_error("Not yet implemented");
|
| - }
|
| -
|
| + : X86Internal::AssemblerX86Base<TargetX8664>(Asm_X8664,
|
| + use_far_branches) {}
|
| ~AssemblerX8664() override = default;
|
|
|
| - void alignFunction() override;
|
| - void padWithNop(intptr_t Padding) override;
|
| - SizeT getBundleAlignLog2Bytes() const override;
|
| - const char *getNonExecPadDirective() const override;
|
| - llvm::ArrayRef<uint8_t> getNonExecBundlePadding() const override;
|
| - void bindCfgNodeLabel(SizeT NodeNumber) override;
|
| - bool fixupIsPCRel(FixupKind Kind) const override;
|
| -
|
| static bool classof(const Assembler *Asm) {
|
| return Asm->getKind() == Asm_X8664;
|
| }
|
| +
|
| +private:
|
| + friend class X86Internal::AssemblerX86Base<TargetX8664>;
|
| +
|
| + template <typename RegType>
|
| + Traits::GPRRegister gprEncoding(const RegType Reg) {
|
| + return static_cast<Traits::GPRRegister>(static_cast<uint8_t>(Reg) & ~0x08);
|
| + }
|
| +
|
| + template <typename RegType> struct IsGPR {
|
| + static constexpr bool value =
|
| + std::is_same<typename std::decay<RegType>::type,
|
| + Traits::ByteRegister>::value ||
|
| + std::is_same<typename std::decay<RegType>::type,
|
| + Traits::GPRRegister>::value;
|
| + };
|
| +
|
| + template <typename RegType, typename RmType>
|
| + void emitRexRB(const Type Ty, const RegType Reg, const RmType Rm) {
|
| + uint8_t W =
|
| + (Ty == IceType_i64) ? Traits::Operand::RexW : Traits::Operand::RexNone;
|
| + uint8_t R = (Reg & 0x08) ? Traits::Operand::RexR : Traits::Operand::RexNone;
|
| + uint8_t B = (Rm & 0x08) ? Traits::Operand::RexB : Traits::Operand::RexNone;
|
| + static constexpr bool RegIsGPR = IsGPR<RegType>::value;
|
| + static constexpr bool RmIsGPR = IsGPR<RmType>::value;
|
| + bool AccessesNewByteRegister =
|
| + (RegIsGPR || RmIsGPR) && isByteSizedType(Ty) &&
|
| + ((((Reg & 0x04) != 0) && ((Reg & 0x08) == 0)) ||
|
| + ((Rm & 0x04) && !(Rm & 0x08)));
|
| + uint8_t Rex = AccessesNewByteRegister ? Traits::Operand::RexBase
|
| + : Traits::Operand::RexNone;
|
| + uint8_t Prefix = Rex | W | R | B;
|
| + if (Prefix != Traits::Operand::RexNone) {
|
| + emitUint8(Prefix);
|
| + }
|
| + }
|
| +
|
| + template <typename RegType> void emitRexB(const Type Ty, const RegType Reg) {
|
| + uint8_t W =
|
| + (Ty == IceType_i64) ? Traits::Operand::RexW : Traits::Operand::RexNone;
|
| + uint8_t B = (Reg & 0x08) ? Traits::Operand::RexB : Traits::Operand::RexNone;
|
| + static constexpr bool RegIsGPR = IsGPR<RegType>::value;
|
| + bool AccessesNewByteRegister = RegIsGPR && isByteSizedType(Ty) &&
|
| + ((Reg & 0x04) != 0) && ((Reg & 0x08) == 0);
|
| + uint8_t Rex = AccessesNewByteRegister ? Traits::Operand::RexBase
|
| + : Traits::Operand::RexNone;
|
| + uint8_t Prefix = Rex | W | B;
|
| + if (Prefix != Traits::Operand::RexNone) {
|
| + emitUint8(Prefix);
|
| + }
|
| + }
|
| +
|
| + template <typename RegType>
|
| + void emitRex(const Type Ty, const Traits::Address &Addr, const RegType Reg) {
|
| + uint8_t W =
|
| + (Ty == IceType_i64) ? Traits::Operand::RexW : Traits::Operand::RexNone;
|
| + uint8_t R = (Reg & 0x08) ? Traits::Operand::RexR : Traits::Operand::RexNone;
|
| + uint8_t X = Addr.rexX();
|
| + uint8_t B = Addr.rexB();
|
| + static constexpr bool RegIsGPR = IsGPR<RegType>::value;
|
| + bool AccessesNewByteRegister = RegIsGPR && isByteSizedType(Ty) &&
|
| + ((Reg & 0x04) != 0) && ((Reg & 0x08) == 0);
|
| + uint8_t Rex = AccessesNewByteRegister ? Traits::Operand::RexBase
|
| + : Traits::Operand::RexNone;
|
| + uint8_t Prefix = Rex | W | R | X | B;
|
| + if (Prefix != Traits::Operand::RexNone) {
|
| + emitUint8(Prefix);
|
| + }
|
| + }
|
| };
|
|
|
| } // end of namespace X8664
|
|
|