Commit 2fea26ca by John Porto

Adds the x86-64 assembler.

As part of this CL, x86-32 assembler tests are also introduced. They were implemented before the x86 base assembler template was modified for x86-64 support. BUG=https://code.google.com/p/nativeclient/issues/detail?id=4077 R=stichnot@chromium.org Review URL: https://codereview.chromium.org/1224173006.
parent 016c56d9
......@@ -168,7 +168,6 @@ SB_LDFLAGS := $(LINKOPTLEVEL) $(LD_EXTRA)
SRCS = \
IceAssembler.cpp \
IceAssemblerX8664.cpp \
IceBrowserCompileServer.cpp \
IceCfg.cpp \
IceCfgNode.cpp \
......@@ -212,9 +211,24 @@ SB_OBJS=$(patsubst %.cpp, $(SB_OBJDIR)/%.o, $(SRCS))
UNITTEST_SRCS = \
BitcodeMunge.cpp \
IceAssemblerX8632Test.cpp \
IceELFSectionTest.cpp \
IceParseInstsTest.cpp
IceParseInstsTest.cpp \
AssemblerX8632/LowLevel.cpp \
AssemblerX8632/DataMov.cpp \
AssemblerX8632/Locked.cpp \
AssemblerX8632/GPRArith.cpp \
AssemblerX8632/XmmArith.cpp \
AssemblerX8632/ControlFlow.cpp \
AssemblerX8632/Other.cpp \
AssemblerX8632/X87.cpp \
AssemblerX8664/LowLevel.cpp \
AssemblerX8664/DataMov.cpp \
AssemblerX8664/Locked.cpp \
AssemblerX8664/GPRArith.cpp \
AssemblerX8664/XmmArith.cpp \
AssemblerX8664/ControlFlow.cpp \
AssemblerX8664/Other.cpp
UNITTEST_OBJS = $(patsubst %.cpp, $(OBJDIR)/unittest/%.o, $(UNITTEST_SRCS))
UNITTEST_LIB_OBJS = $(filter-out $(OBJDIR)/main.o,$(OBJS))
......@@ -271,6 +285,7 @@ $(UNITTEST_OBJS): $(OBJDIR)/unittest/%.o: unittest/%.cpp \
unittest/*.h src/*.h src/*.def
$(CXX) -c $(CXXFLAGS) \
-Isrc/ \
-Iunittest/ \
-I$(LLVM_SRC_PATH)/utils/unittest/googletest/include \
-I$(LLVM_SRC_PATH) \
-DGTEST_HAS_RTTI=0 -DGTEST_USE_OWN_TR1_TUPLE \
......@@ -279,7 +294,7 @@ $(UNITTEST_OBJS): $(OBJDIR)/unittest/%.o: unittest/%.cpp \
$(OBJS): | $(OBJDIR)
$(SB_OBJS): | $(SB_OBJDIR)
$(UNITTEST_OBJS): | $(OBJDIR)/unittest
$(UNITTEST_OBJS): | $(OBJDIR)/unittest $(OBJDIR)/unittest/AssemblerX8632 $(OBJDIR)/unittest/AssemblerX8664
$(OBJDIR):
@mkdir -p $@
......@@ -289,6 +304,11 @@ $(SB_OBJDIR):
$(OBJDIR)/unittest: $(OBJDIR)
@mkdir -p $@
$(OBJDIR)/unittest/AssemblerX8632: $(OBJDIR)/unittest
@mkdir -p $@
$(OBJDIR)/unittest/AssemblerX8664: $(OBJDIR)/unittest
@mkdir -p $@
RT_SRC := runtime/szrt.c runtime/szrt_ll.ll runtime/szrt_profiler.c
RT_OBJ := build/runtime/szrt_native_x8632.o build/runtime/szrt_sb_x8632.o \
build/runtime/szrt_native_arm32.o build/runtime/szrt_sb_arm32.o
......
//===- subzero/src/IceAssemblerX8664.cpp ----------------------------------===//
//
// The Subzero Code Generator
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file implements the Assembler class for x86-64.
///
//===----------------------------------------------------------------------===//
#include "IceAssemblerX8664.h"
namespace Ice {
namespace X8664 {
void AssemblerX8664::alignFunction() {
llvm::report_fatal_error("Not yet implemented");
}
void AssemblerX8664::padWithNop(intptr_t) {
llvm::report_fatal_error("Not yet implemented");
}
SizeT AssemblerX8664::getBundleAlignLog2Bytes() const {
llvm::report_fatal_error("Not yet implemented");
}
const char *AssemblerX8664::getNonExecPadDirective() const {
llvm::report_fatal_error("Not yet implemented");
}
llvm::ArrayRef<uint8_t> AssemblerX8664::getNonExecBundlePadding() const {
llvm::report_fatal_error("Not yet implemented");
}
void AssemblerX8664::bindCfgNodeLabel(SizeT) {
llvm::report_fatal_error("Not yet implemented");
}
bool AssemblerX8664::fixupIsPCRel(FixupKind) const {
llvm::report_fatal_error("Not yet implemented");
}
} // namespace X8664
} // namespace Ice
//===- 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,33 +24,32 @@
#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"
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;
}
......
......@@ -21,6 +21,7 @@
namespace Ice {
class CondX8664 {
public:
/// An enum of condition codes used for branches and cmov. The enum value
/// should match the value used to encode operands in binary instructions.
enum BrCond {
......
......@@ -15,46 +15,51 @@
#ifndef SUBZERO_SRC_ICEINSTX8664_DEF
#define SUBZERO_SRC_ICEINSTX8664_DEF
// NOTE: we use the 32bit register names for two reasons:
// (1) it makes it easier to implement the x86 assembler template.
// (2) when generating code, subzero defaults to using 32 bit registers,
// so using the 32 bit register name would hopefully make this design
// more explicit.
// NOTE: esp is not considered isInt, to avoid register allocating it.
#define REGX8664_GPR_TABLE \
/* val, encode, name64, name, name16, name8, scratch, preserved, stackptr, \
frameptr, isInt, isFP */ \
X(Reg_rax, = 0, "rax", "eax" , "ax" , "al" , 1, 0, 0, 0, 1, 0) \
X(Reg_rcx, = Reg_rax + 1, "rcx", "ecx" , "cx" , "cl" , 1, 0, 0, 0, 1, 0) \
X(Reg_rdx, = Reg_rax + 2, "rdx", "edx" , "dx" , "dl" , 1, 0, 0, 0, 1, 0) \
X(Reg_rbx, = Reg_rax + 3, "rbx", "ebx" , "bx" , "bl" , 0, 1, 0, 0, 1, 0) \
X(Reg_rsp, = Reg_rax + 4, "rsp", "esp" , "sp" , "spl" , 0, 0, 1, 0, 0, 0) \
X(Reg_rbp, = Reg_rax + 5, "rbp", "ebp" , "bp" , "bpl" , 0, 0, 0, 1, 1, 0) \
X(Reg_rsi, = Reg_rax + 6, "rsi", "esi" , "si" , "sil" , 1, 0, 0, 0, 1, 0) \
X(Reg_rdi, = Reg_rax + 7, "rdi", "edi" , "di" , "dil" , 1, 0, 0, 0, 1, 0) \
X(Reg_r8, = Reg_rax + 8, "r8" , "r8d" , "r8w", "r8l" , 1, 0, 0, 0, 1, 0) \
X(Reg_r9, = Reg_rax + 9, "r9" , "r9d" , "r9w", "r9l" , 1, 0, 0, 0, 1, 0) \
X(Reg_r10, = Reg_rax + 10, "r10", "r10d", "r10w", "r10l", 1, 0, 0, 0, 1, 0) \
X(Reg_r11, = Reg_rax + 11, "r11", "r11d", "r11w", "r11l", 1, 0, 0, 0, 1, 0) \
X(Reg_r12, = Reg_rax + 12, "r12", "r12d", "r12w", "r12l", 0, 1, 0, 0, 1, 0) \
X(Reg_r13, = Reg_rax + 13, "r13", "r13d", "r13w", "r12l", 0, 1, 0, 0, 1, 0) \
X(Reg_r14, = Reg_rax + 14, "r14", "r14d", "r14w", "r14l", 0, 1, 0, 0, 1, 0) \
X(Reg_r15, = Reg_rax + 15, "r15", "r15d", "r15w", "r15l", 0, 1, 0, 0, 1, 0)
X(Reg_eax, = 0, "rax", "eax" , "ax" , "al" , 1, 0, 0, 0, 1, 0) \
X(Reg_ecx, = 1, "rcx", "ecx" , "cx" , "cl" , 1, 0, 0, 0, 1, 0) \
X(Reg_edx, = 2, "rdx", "edx" , "dx" , "dl" , 1, 0, 0, 0, 1, 0) \
X(Reg_ebx, = 3, "rbx", "ebx" , "bx" , "bl" , 0, 1, 0, 0, 1, 0) \
X(Reg_esp, = 4, "rsp", "esp" , "sp" , "spl" , 0, 0, 1, 0, 0, 0) \
X(Reg_ebp, = 5, "rbp", "ebp" , "bp" , "bpl" , 0, 0, 0, 1, 1, 0) \
X(Reg_esi, = 6, "rsi", "esi" , "si" , "sil" , 1, 0, 0, 0, 1, 0) \
X(Reg_edi, = 7, "rdi", "edi" , "di" , "dil" , 1, 0, 0, 0, 1, 0) \
X(Reg_r8d, = 8, "r8" , "r8d" , "r8w", "r8l" , 1, 0, 0, 0, 1, 0) \
X(Reg_r9d, = 9, "r9" , "r9d" , "r9w", "r9l" , 1, 0, 0, 0, 1, 0) \
X(Reg_r10d, = 10, "r10", "r10d", "r10w", "r10l", 1, 0, 0, 0, 1, 0) \
X(Reg_r11d, = 11, "r11", "r11d", "r11w", "r11l", 1, 0, 0, 0, 1, 0) \
X(Reg_r12d, = 12, "r12", "r12d", "r12w", "r12l", 0, 1, 0, 0, 1, 0) \
X(Reg_r13d, = 13, "r13", "r13d", "r13w", "r12l", 0, 1, 0, 0, 1, 0) \
X(Reg_r14d, = 14, "r14", "r14d", "r14w", "r14l", 0, 1, 0, 0, 1, 0) \
X(Reg_r15d, = 15, "r15", "r15d", "r15w", "r15l", 0, 1, 0, 0, 1, 0)
#define REGX8664_XMM_TABLE \
/* val, encode, name64, name, name16, name8, scratch, preserved, stackptr, \
frameptr, isInt, isFP */ \
X(Reg_xmm0, = 0, "xmm0" , "", "", "", 1, 0, 0, 0, 0, 1) \
X(Reg_xmm1, = Reg_xmm0 + 1, "xmm1" , "", "", "", 1, 0, 0, 0, 0, 1) \
X(Reg_xmm2, = Reg_xmm0 + 2, "xmm2" , "", "", "", 1, 0, 0, 0, 0, 1) \
X(Reg_xmm3, = Reg_xmm0 + 3, "xmm3" , "", "", "", 1, 0, 0, 0, 0, 1) \
X(Reg_xmm4, = Reg_xmm0 + 4, "xmm4" , "", "", "", 1, 0, 0, 0, 0, 1) \
X(Reg_xmm5, = Reg_xmm0 + 5, "xmm5" , "", "", "", 1, 0, 0, 0, 0, 1) \
X(Reg_xmm6, = Reg_xmm0 + 6, "xmm6" , "", "", "", 1, 0, 0, 0, 0, 1) \
X(Reg_xmm7, = Reg_xmm0 + 7, "xmm7" , "", "", "", 1, 0, 0, 0, 0, 1) \
X(Reg_xmm8, = Reg_xmm0 + 8, "xmm8" , "", "", "", 1, 0, 0, 0, 0, 1) \
X(Reg_xmm9, = Reg_xmm0 + 9, "xmm9" , "", "", "", 1, 0, 0, 0, 0, 1) \
X(Reg_xmm10, = Reg_xmm0 + 10, "xmm10", "", "", "", 1, 0, 0, 0, 0, 1) \
X(Reg_xmm11, = Reg_xmm0 + 11, "xmm11", "", "", "", 1, 0, 0, 0, 0, 1) \
X(Reg_xmm12, = Reg_xmm0 + 12, "xmm12", "", "", "", 1, 0, 0, 0, 0, 1) \
X(Reg_xmm13, = Reg_xmm0 + 13, "xmm13", "", "", "", 1, 0, 0, 0, 0, 1) \
X(Reg_xmm14, = Reg_xmm0 + 14, "xmm14", "", "", "", 1, 0, 0, 0, 0, 1) \
X(Reg_xmm15, = Reg_xmm0 + 15, "xmm15", "", "", "", 1, 0, 0, 0, 0, 1)
X(Reg_xmm0, = 0, "xmm0" , "", "", "", 1, 0, 0, 0, 0, 1) \
X(Reg_xmm1, = 1, "xmm1" , "", "", "", 1, 0, 0, 0, 0, 1) \
X(Reg_xmm2, = 2, "xmm2" , "", "", "", 1, 0, 0, 0, 0, 1) \
X(Reg_xmm3, = 3, "xmm3" , "", "", "", 1, 0, 0, 0, 0, 1) \
X(Reg_xmm4, = 4, "xmm4" , "", "", "", 1, 0, 0, 0, 0, 1) \
X(Reg_xmm5, = 5, "xmm5" , "", "", "", 1, 0, 0, 0, 0, 1) \
X(Reg_xmm6, = 6, "xmm6" , "", "", "", 1, 0, 0, 0, 0, 1) \
X(Reg_xmm7, = 7, "xmm7" , "", "", "", 1, 0, 0, 0, 0, 1) \
X(Reg_xmm8, = 8, "xmm8" , "", "", "", 1, 0, 0, 0, 0, 1) \
X(Reg_xmm9, = 9, "xmm9" , "", "", "", 1, 0, 0, 0, 0, 1) \
X(Reg_xmm10, = 10, "xmm10", "", "", "", 1, 0, 0, 0, 0, 1) \
X(Reg_xmm11, = 11, "xmm11", "", "", "", 1, 0, 0, 0, 0, 1) \
X(Reg_xmm12, = 12, "xmm12", "", "", "", 1, 0, 0, 0, 0, 1) \
X(Reg_xmm13, = 13, "xmm13", "", "", "", 1, 0, 0, 0, 0, 1) \
X(Reg_xmm14, = 14, "xmm14", "", "", "", 1, 0, 0, 0, 0, 1) \
X(Reg_xmm15, = 15, "xmm15", "", "", "", 1, 0, 0, 0, 0, 1)
//#define X(val, encode, name, name32, name16, name8, scratch, preserved,
// stackptr, frameptr, isI8, isInt, isFP)
......@@ -77,8 +82,8 @@
#define REGX8664_TABLE_BOUNDS \
/* val , init */ \
X(Reg_GPR_First, = Reg_rax ) \
X(Reg_GPR_Last , = Reg_r15 ) \
X(Reg_GPR_First, = Reg_eax ) \
X(Reg_GPR_Last , = Reg_r15d ) \
X(Reg_XMM_First, = Reg_xmm0 ) \
X(Reg_XMM_Last , = Reg_xmm15)
// define X(val, init)
......
......@@ -79,10 +79,6 @@ public:
}
static inline ByteRegister getEncodedByteReg(int32_t RegNum) {
// In x86-64, AH is not encodable when the REX prefix is used; the same
// encoding is used for spl. Therefore, ah needs special handling.
if (RegNum == Reg_ah)
return Encoded_Reg_spl;
return ByteRegister(RegNum - Reg_GPR_First);
}
......
......@@ -48,6 +48,13 @@ template <> struct MachineTraits<TargetX8632> {
// \/_/\/_/\/_____/\/_/ \/_/
//
//----------------------------------------------------------------------------
static constexpr bool Is64Bit = false;
static constexpr bool HasPopa = true;
static constexpr bool HasPusha = true;
static constexpr bool UsesX87 = true;
static constexpr ::Ice::RegX8632::GPRRegister Last8BitGPR =
::Ice::RegX8632::GPRRegister::Encoded_Reg_ebx;
enum ScaleFactor { TIMES_1 = 0, TIMES_2 = 1, TIMES_4 = 2, TIMES_8 = 3 };
using GPRRegister = ::Ice::RegX8632::GPRRegister;
......
//===- subzero/src/IceTargetLoweringX8664Traits.h - x86-64 traits -*- C++ -*-=//
//
// The Subzero Code Generator
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// This file declares the X8664 Target Lowering Traits.
///
//===----------------------------------------------------------------------===//
#ifndef SUBZERO_SRC_ICETARGETLOWERINGX8664TRAITS_H
#define SUBZERO_SRC_ICETARGETLOWERINGX8664TRAITS_H
#include "IceAssembler.h"
#include "IceConditionCodesX8664.h"
#include "IceDefs.h"
#include "IceInst.h"
#include "IceInstX8664.def"
#include "IceOperand.h"
#include "IceRegistersX8664.h"
#include "IceTargetLowering.h"
namespace Ice {
class TargetX8664;
namespace X8664 {
class AssemblerX8664;
} // end of namespace X8664
namespace X86Internal {
template <class Machine> struct Insts;
template <class Machine> struct MachineTraits;
template <> struct MachineTraits<TargetX8664> {
//----------------------------------------------------------------------------
// ______ ______ __ __
// /\ __ \/\ ___\/\ "-./ \
// \ \ __ \ \___ \ \ \-./\ \
// \ \_\ \_\/\_____\ \_\ \ \_\
// \/_/\/_/\/_____/\/_/ \/_/
//
//----------------------------------------------------------------------------
static constexpr bool Is64Bit = true;
static constexpr bool HasPopa = false;
static constexpr bool HasPusha = false;
static constexpr bool UsesX87 = false;
static constexpr ::Ice::RegX8664::GPRRegister Last8BitGPR =
::Ice::RegX8664::GPRRegister::Encoded_Reg_r15d;
enum ScaleFactor { TIMES_1 = 0, TIMES_2 = 1, TIMES_4 = 2, TIMES_8 = 3 };
using GPRRegister = ::Ice::RegX8664::GPRRegister;
using XmmRegister = ::Ice::RegX8664::XmmRegister;
using ByteRegister = ::Ice::RegX8664::ByteRegister;
using Cond = ::Ice::CondX8664;
using RegisterSet = ::Ice::RegX8664;
static const GPRRegister Encoded_Reg_Accumulator = RegX8664::Encoded_Reg_eax;
static const GPRRegister Encoded_Reg_Counter = RegX8664::Encoded_Reg_ecx;
static const FixupKind PcRelFixup = llvm::ELF::R_386_PC32; // TODO(jpp): ???
class Operand {
public:
enum RexBits {
RexNone = 0x00,
RexBase = 0x40,
RexW = RexBase | (1 << 3),
RexR = RexBase | (1 << 2),
RexX = RexBase | (1 << 1),
RexB = RexBase | (1 << 0),
};
Operand(const Operand &other)
: fixup_(other.fixup_), rex_(other.rex_), length_(other.length_) {
memmove(&encoding_[0], &other.encoding_[0], other.length_);
}
Operand &operator=(const Operand &other) {
length_ = other.length_;
fixup_ = other.fixup_;
rex_ = other.rex_;
memmove(&encoding_[0], &other.encoding_[0], other.length_);
return *this;
}
uint8_t mod() const { return (encoding_at(0) >> 6) & 3; }
uint8_t rexX() const { return (rex_ & RexX) != RexX ? RexNone : RexX; }
uint8_t rexB() const { return (rex_ & RexB) != RexB ? RexNone : RexB; }
GPRRegister rm() const {
return static_cast<GPRRegister>((rexB() != 0 ? 0x08 : 0) |
(encoding_at(0) & 7));
}
ScaleFactor scale() const {
return static_cast<ScaleFactor>((encoding_at(1) >> 6) & 3);
}
GPRRegister index() const {
return static_cast<GPRRegister>((rexX() != 0 ? 0x08 : 0) |
((encoding_at(1) >> 3) & 7));
}
GPRRegister base() const {
return static_cast<GPRRegister>((rexB() != 0 ? 0x08 : 0) |
(encoding_at(1) & 7));
}
int8_t disp8() const {
assert(length_ >= 2);
return static_cast<int8_t>(encoding_[length_ - 1]);
}
int32_t disp32() const {
assert(length_ >= 5);
return bit_copy<int32_t>(encoding_[length_ - 4]);
}
AssemblerFixup *fixup() const { return fixup_; }
protected:
Operand() : fixup_(nullptr), length_(0) {} // Needed by subclass Address.
void SetModRM(int mod, GPRRegister rm) {
assert((mod & ~3) == 0);
encoding_[0] = (mod << 6) | (rm & 0x07);
rex_ = (rm & 0x08) ? RexB : RexNone;
length_ = 1;
}
void SetSIB(ScaleFactor scale, GPRRegister index, GPRRegister base) {
assert(length_ == 1);
assert((scale & ~3) == 0);
encoding_[1] = (scale << 6) | ((index & 0x07) << 3) | (base & 0x07);
rex_ =
((base & 0x08) ? RexB : RexNone) | ((index & 0x08) ? RexX : RexNone);
length_ = 2;
}
void SetDisp8(int8_t disp) {
assert(length_ == 1 || length_ == 2);
encoding_[length_++] = static_cast<uint8_t>(disp);
}
void SetDisp32(int32_t disp) {
assert(length_ == 1 || length_ == 2);
intptr_t disp_size = sizeof(disp);
memmove(&encoding_[length_], &disp, disp_size);
length_ += disp_size;
}
void SetFixup(AssemblerFixup *fixup) { fixup_ = fixup; }
private:
AssemblerFixup *fixup_;
uint8_t rex_ = 0;
uint8_t encoding_[6];
uint8_t length_;
explicit Operand(GPRRegister reg) : fixup_(nullptr) { SetModRM(3, reg); }
/// Get the operand encoding byte at the given index.
uint8_t encoding_at(intptr_t index) const {
assert(index >= 0 && index < length_);
return encoding_[index];
}
/// Returns whether or not this operand is really the given register in
/// disguise. Used from the assembler to generate better encodings.
bool IsRegister(GPRRegister reg) const {
return ((encoding_[0] & 0xF8) ==
0xC0) // Addressing mode is register only.
&&
(rm() == reg); // Register codes match.
}
template <class> friend class AssemblerX86Base;
};
class Address : public Operand {
Address() = delete;
public:
Address(const Address &other) : Operand(other) {}
Address &operator=(const Address &other) {
Operand::operator=(other);
return *this;
}
Address(GPRRegister base, int32_t disp) {
if (disp == 0 && (base & 7) != RegX8664::Encoded_Reg_ebp) {
SetModRM(0, base);
if ((base & 7) == RegX8664::Encoded_Reg_esp)
SetSIB(TIMES_1, RegX8664::Encoded_Reg_esp, base);
} else if (Utils::IsInt(8, disp)) {
SetModRM(1, base);
if ((base & 7) == RegX8664::Encoded_Reg_esp)
SetSIB(TIMES_1, RegX8664::Encoded_Reg_esp, base);
SetDisp8(disp);
} else {
SetModRM(2, base);
if ((base & 7) == RegX8664::Encoded_Reg_esp)
SetSIB(TIMES_1, RegX8664::Encoded_Reg_esp, base);
SetDisp32(disp);
}
}
Address(GPRRegister index, ScaleFactor scale, int32_t disp) {
assert(index != RegX8664::Encoded_Reg_esp); // Illegal addressing mode.
SetModRM(0, RegX8664::Encoded_Reg_esp);
SetSIB(scale, index, RegX8664::Encoded_Reg_ebp);
SetDisp32(disp);
}
Address(GPRRegister base, GPRRegister index, ScaleFactor scale,
int32_t disp) {
assert(index != RegX8664::Encoded_Reg_esp); // Illegal addressing mode.
if (disp == 0 && (base & 7) != RegX8664::Encoded_Reg_ebp) {
SetModRM(0, RegX8664::Encoded_Reg_esp);
SetSIB(scale, index, base);
} else if (Utils::IsInt(8, disp)) {
SetModRM(1, RegX8664::Encoded_Reg_esp);
SetSIB(scale, index, base);
SetDisp8(disp);
} else {
SetModRM(2, RegX8664::Encoded_Reg_esp);
SetSIB(scale, index, base);
SetDisp32(disp);
}
}
// PcRelTag is a special tag for requesting rip-relative addressing in
// X86-64.
// TODO(jpp): this is bogus. remove.
enum AbsoluteTag { ABSOLUTE };
Address(AbsoluteTag, const uintptr_t Addr) {
SetModRM(0, RegX8664::Encoded_Reg_ebp);
SetDisp32(Addr);
}
// TODO(jpp): remove this.
static Address Absolute(const uintptr_t Addr) {
return Address(ABSOLUTE, Addr);
}
Address(AbsoluteTag, RelocOffsetT Offset, AssemblerFixup *Fixup) {
SetModRM(0, RegX8664::Encoded_Reg_ebp);
// Use the Offset in the displacement for now. If we decide to process
// fixups later, we'll need to patch up the emitted displacement.
SetDisp32(Offset);
SetFixup(Fixup);
}
// TODO(jpp): remove this.
static Address Absolute(RelocOffsetT Offset, AssemblerFixup *Fixup) {
return Address(ABSOLUTE, Offset, Fixup);
}
static Address ofConstPool(Assembler *Asm, const Constant *Imm) {
// TODO(jpp): ???
AssemblerFixup *Fixup = Asm->createFixup(llvm::ELF::R_386_32, Imm);
const RelocOffsetT Offset = 0;
return Address(ABSOLUTE, Offset, Fixup);
}
};
//----------------------------------------------------------------------------
// __ ______ __ __ ______ ______ __ __ __ ______
// /\ \ /\ __ \/\ \ _ \ \/\ ___\/\ == \/\ \/\ "-.\ \/\ ___\
// \ \ \___\ \ \/\ \ \ \/ ".\ \ \ __\\ \ __<\ \ \ \ \-. \ \ \__ \
// \ \_____\ \_____\ \__/".~\_\ \_____\ \_\ \_\ \_\ \_\\"\_\ \_____\
// \/_____/\/_____/\/_/ \/_/\/_____/\/_/ /_/\/_/\/_/ \/_/\/_____/
//
//----------------------------------------------------------------------------
using Assembler = X8664::AssemblerX8664;
};
} // end of namespace X86Internal
namespace X8664 {
using Traits = ::Ice::X86Internal::MachineTraits<TargetX8664>;
} // end of namespace X8664
} // end of namespace Ice
#endif // SUBZERO_SRC_ICETARGETLOWERINGX8664TRAITS_H
This source diff could not be displayed because it is too large. You can view the blob instead.
//===- subzero/unittest/AssemblerX8632/Other.cpp --------------------------===//
//
// The Subzero Code Generator
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "AssemblerX8632/TestUtil.h"
namespace Ice {
namespace X8632 {
namespace Test {
namespace {
TEST_F(AssemblerX8632LowLevelTest, Nop) {
#define TestImpl(Size, ...) \
do { \
static constexpr char TestString[] = "(" #Size ", " #__VA_ARGS__ ")"; \
__ nop(Size); \
ASSERT_EQ(Size##u, codeBytesSize()) << TestString; \
ASSERT_TRUE(verifyBytes<Size>(codeBytes(), __VA_ARGS__)) << TestString; \
reset(); \
} while (0);
TestImpl(1, 0x90);
TestImpl(2, 0x66, 0x90);
TestImpl(3, 0x0F, 0x1F, 0x00);
TestImpl(4, 0x0F, 0x1F, 0x40, 0x00);
TestImpl(5, 0x0F, 0x1F, 0x44, 0x00, 0x00);
TestImpl(6, 0x66, 0x0F, 0x1F, 0x44, 0x00, 0x00);
TestImpl(7, 0x0F, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00);
TestImpl(8, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00);
#undef TestImpl
}
TEST_F(AssemblerX8632LowLevelTest, Int3) {
__ int3();
static constexpr uint32_t ByteCount = 1;
ASSERT_EQ(ByteCount, codeBytesSize());
verifyBytes<ByteCount>(codeBytes(), 0xCC);
}
TEST_F(AssemblerX8632LowLevelTest, Hlt) {
__ hlt();
static constexpr uint32_t ByteCount = 1;
ASSERT_EQ(ByteCount, codeBytesSize());
verifyBytes<ByteCount>(codeBytes(), 0xF4);
}
TEST_F(AssemblerX8632LowLevelTest, Ud2) {
__ ud2();
static constexpr uint32_t ByteCount = 2;
ASSERT_EQ(ByteCount, codeBytesSize());
verifyBytes<ByteCount>(codeBytes(), 0x0F, 0x0B);
}
TEST_F(AssemblerX8632LowLevelTest, EmitSegmentOverride) {
#define TestImpl(Prefix) \
do { \
static constexpr uint8_t ByteCount = 1; \
__ emitSegmentOverride(Prefix); \
ASSERT_EQ(ByteCount, codeBytesSize()) << Prefix; \
verifyBytes<ByteCount>(codeBytes(), Prefix); \
reset(); \
} while (0)
TestImpl(0x26);
TestImpl(0x2E);
TestImpl(0x36);
TestImpl(0x3E);
TestImpl(0x64);
TestImpl(0x65);
TestImpl(0x66);
TestImpl(0x67);
#undef TestImpl
}
} // end of anonymous namespace
} // end of namespace Test
} // end of namespace X8632
} // end of namespace Ice
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
//===- subzero/unittest/AssemblerX8664/GPRArith.cpp -----------------------===//
//
// The Subzero Code Generator
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "AssemblerX8664/TestUtil.h"
namespace Ice {
namespace X8664 {
namespace Test {
namespace {
TEST_F(AssemblerX8664LowLevelTest, Nop) {
#define TestImpl(Size, ...) \
do { \
static constexpr char TestString[] = "(" #Size ", " #__VA_ARGS__ ")"; \
__ nop(Size); \
ASSERT_EQ(Size##u, codeBytesSize()) << TestString; \
ASSERT_TRUE(verifyBytes<Size>(codeBytes(), __VA_ARGS__)) << TestString; \
reset(); \
} while (0);
TestImpl(1, 0x90);
TestImpl(2, 0x66, 0x90);
TestImpl(3, 0x0F, 0x1F, 0x00);
TestImpl(4, 0x0F, 0x1F, 0x40, 0x00);
TestImpl(5, 0x0F, 0x1F, 0x44, 0x00, 0x00);
TestImpl(6, 0x66, 0x0F, 0x1F, 0x44, 0x00, 0x00);
TestImpl(7, 0x0F, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00);
TestImpl(8, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00);
#undef TestImpl
}
TEST_F(AssemblerX8664LowLevelTest, Int3) {
__ int3();
static constexpr uint32_t ByteCount = 1;
ASSERT_EQ(ByteCount, codeBytesSize());
verifyBytes<ByteCount>(codeBytes(), 0xCC);
}
TEST_F(AssemblerX8664LowLevelTest, Hlt) {
__ hlt();
static constexpr uint32_t ByteCount = 1;
ASSERT_EQ(ByteCount, codeBytesSize());
verifyBytes<ByteCount>(codeBytes(), 0xF4);
}
TEST_F(AssemblerX8664LowLevelTest, Ud2) {
__ ud2();
static constexpr uint32_t ByteCount = 2;
ASSERT_EQ(ByteCount, codeBytesSize());
verifyBytes<ByteCount>(codeBytes(), 0x0F, 0x0B);
}
} // end of anonymous namespace
} // end of namespace Test
} // end of namespace X8664
} // end of namespace Ice
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment