Skip to content

Commit

Permalink
Adding skeleton for unit testing Hexagon Code Emission
Browse files Browse the repository at this point in the history
Adding and modifying CMakeLists.txt files to run unit tests under
unittests/Target/* if the directory exists.  Adding basic unit test to check
that code emitter object can be retrieved.

Differential Revision: http://reviews.llvm.org/D5523
Change by: Colin LeMahieu

llvm-svn: 218986
  • Loading branch information
Sid Manning committed Oct 3, 2014
1 parent 1964078 commit 7da3f9a
Show file tree
Hide file tree
Showing 7 changed files with 179 additions and 8 deletions.
1 change: 1 addition & 0 deletions llvm/lib/Target/Hexagon/CMakeLists.txt
Expand Up @@ -2,6 +2,7 @@ set(LLVM_TARGET_DEFINITIONS Hexagon.td)

tablegen(LLVM HexagonGenRegisterInfo.inc -gen-register-info)
tablegen(LLVM HexagonGenInstrInfo.inc -gen-instr-info)
tablegen(LLVM HexagonGenMCCodeEmitter.inc -gen-emitter)
tablegen(LLVM HexagonGenAsmWriter.inc -gen-asm-writer)
tablegen(LLVM HexagonGenDAGISel.inc -gen-dag-isel)
tablegen(LLVM HexagonGenCallingConv.inc -gen-callingconv)
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Target/Hexagon/MCTargetDesc/CMakeLists.txt
@@ -1,5 +1,8 @@
add_llvm_library(LLVMHexagonDesc
HexagonMCAsmInfo.cpp
HexagonMCCodeEmitter.cpp
HexagonMCInst.cpp
HexagonMCTargetDesc.cpp
)

add_dependencies(LLVMHexagonDesc HexagonCommonTableGen)
88 changes: 88 additions & 0 deletions llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.cpp
@@ -0,0 +1,88 @@
//===-- HexagonMCCodeEmitter.cpp - Hexagon Target Descriptions ------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "Hexagon.h"
#include "MCTargetDesc/HexagonBaseInfo.h"
#include "MCTargetDesc/HexagonMCCodeEmitter.h"
#include "MCTargetDesc/HexagonMCTargetDesc.h"
#include "MCTargetDesc/HexagonMCInst.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"

#define DEBUG_TYPE "mccodeemitter"

using namespace llvm;
using namespace Hexagon;

STATISTIC(MCNumEmitted, "Number of MC instructions emitted");

namespace {
/// \brief 10.6 Instruction Packets
/// \brief Possible values for instruction packet parse field.
enum class ParseField { duplex = 0x0, last0 = 0x1, last1 = 0x2, end = 0x3 };
/// \brief Returns the packet bits based on instruction position.
uint32_t getPacketBits(HexagonMCInst const &HMI) {
unsigned const ParseFieldOffset = 14;
ParseField Field = HMI.isPacketEnd() ? ParseField::end : ParseField::last0;
return static_cast <uint32_t> (Field) << ParseFieldOffset;
}
void emitLittleEndian(uint64_t Binary, raw_ostream &OS) {
OS << static_cast<uint8_t>((Binary >> 0x00) & 0xff);
OS << static_cast<uint8_t>((Binary >> 0x08) & 0xff);
OS << static_cast<uint8_t>((Binary >> 0x10) & 0xff);
OS << static_cast<uint8_t>((Binary >> 0x18) & 0xff);
}
}

HexagonMCCodeEmitter::HexagonMCCodeEmitter(MCInstrInfo const &aMII,
MCSubtargetInfo const &aMST,
MCContext &aMCT)
: MST(aMST), MCT(aMCT) {}

void HexagonMCCodeEmitter::EncodeInstruction(MCInst const &MI, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups,
MCSubtargetInfo const &STI) const {
HexagonMCInst const &HMB = static_cast<HexagonMCInst const &>(MI);
uint64_t Binary = getBinaryCodeForInstr(HMB, Fixups, STI) | getPacketBits(HMB);
assert(HMB.getDesc().getSize() == 4 && "All instructions should be 32bit");
emitLittleEndian(Binary, OS);
++MCNumEmitted;
}

unsigned
HexagonMCCodeEmitter::getMachineOpValue(MCInst const &MI, MCOperand const &MO,
SmallVectorImpl<MCFixup> &Fixups,
MCSubtargetInfo const &STI) const {
if (MO.isReg())
return MCT.getRegisterInfo()->getEncodingValue(MO.getReg());
if (MO.isImm())
return static_cast<unsigned>(MO.getImm());
llvm_unreachable("Only Immediates and Registers implemented right now");
}

MCSubtargetInfo const &HexagonMCCodeEmitter::getSubtargetInfo() const {
return MST;
}

MCCodeEmitter *llvm::createHexagonMCCodeEmitter(MCInstrInfo const &MII,
MCRegisterInfo const &MRI,
MCSubtargetInfo const &MST,
MCContext &MCT) {
return new HexagonMCCodeEmitter(MII, MST, MCT);
}

#include "HexagonGenMCCodeEmitter.inc"
60 changes: 60 additions & 0 deletions llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCCodeEmitter.h
@@ -0,0 +1,60 @@
//===-- HexagonMCCodeEmitter.h - Hexagon Target Descriptions ----*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
///
/// \file
/// \brief Definition for classes that emit Hexagon machine code from MCInsts
///
//===----------------------------------------------------------------------===//

#ifndef HEXAGONMCCODEEMITTER_H
#define HEXAGONMCCODEEMITTER_H

#include "llvm/MC/MCCodeEmitter.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/raw_ostream.h"

namespace llvm {

class HexagonMCCodeEmitter : public MCCodeEmitter {
MCSubtargetInfo const &MST;
MCContext &MCT;

public:
HexagonMCCodeEmitter(MCInstrInfo const &aMII, MCSubtargetInfo const &aMST,
MCContext &aMCT);

MCSubtargetInfo const &getSubtargetInfo() const;

void EncodeInstruction(MCInst const &MI, raw_ostream &OS,
SmallVectorImpl<MCFixup> &Fixups,
MCSubtargetInfo const &STI) const override;

// getBinaryCodeForInstr - TableGen'erated function for getting the
// binary encoding for an instruction.
uint64_t getBinaryCodeForInstr(MCInst const &MI,
SmallVectorImpl<MCFixup> &Fixups,
MCSubtargetInfo const &STI) const;

/// \brief Return binary encoding of operand.
unsigned getMachineOpValue(MCInst const &MI, MCOperand const &MO,
SmallVectorImpl<MCFixup> &Fixups,
MCSubtargetInfo const &STI) const;

private:
HexagonMCCodeEmitter(HexagonMCCodeEmitter const &) = delete;
void operator=(HexagonMCCodeEmitter const &) = delete;
}; // class HexagonMCCodeEmitter

} // namespace llvm

#endif /* HEXAGONMCCODEEMITTER_H */
20 changes: 12 additions & 8 deletions llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.cpp
Expand Up @@ -46,9 +46,8 @@ static MCRegisterInfo *createHexagonMCRegisterInfo(StringRef TT) {
return X;
}

static MCSubtargetInfo *createHexagonMCSubtargetInfo(StringRef TT,
StringRef CPU,
StringRef FS) {
static MCSubtargetInfo *
createHexagonMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS) {
MCSubtargetInfo *X = new MCSubtargetInfo();
InitHexagonMCSubtargetInfo(X, TT, CPU, FS);
return X;
Expand All @@ -59,16 +58,16 @@ static MCAsmInfo *createHexagonMCAsmInfo(const MCRegisterInfo &MRI,
MCAsmInfo *MAI = new HexagonMCAsmInfo(TT);

// VirtualFP = (R30 + #0).
MCCFIInstruction Inst = MCCFIInstruction::createDefCfa(
nullptr, Hexagon::R30, 0);
MCCFIInstruction Inst =
MCCFIInstruction::createDefCfa(nullptr, Hexagon::R30, 0);
MAI->addInitialFrameState(Inst);

return MAI;
}

static MCCodeGenInfo *createHexagonMCCodeGenInfo(StringRef TT, Reloc::Model RM,
CodeModel::Model CM,
CodeGenOpt::Level OL) {
CodeModel::Model CM,
CodeGenOpt::Level OL) {
MCCodeGenInfo *X = new MCCodeGenInfo();
// For the time being, use static relocations, since there's really no
// support for PIC yet.
Expand All @@ -86,7 +85,8 @@ extern "C" void LLVMInitializeHexagonTargetMC() {
createHexagonMCCodeGenInfo);

// Register the MC instruction info.
TargetRegistry::RegisterMCInstrInfo(TheHexagonTarget, createHexagonMCInstrInfo);
TargetRegistry::RegisterMCInstrInfo(TheHexagonTarget,
createHexagonMCInstrInfo);

// Register the MC register info.
TargetRegistry::RegisterMCRegInfo(TheHexagonTarget,
Expand All @@ -95,4 +95,8 @@ extern "C" void LLVMInitializeHexagonTargetMC() {
// Register the MC subtarget info.
TargetRegistry::RegisterMCSubtargetInfo(TheHexagonTarget,
createHexagonMCSubtargetInfo);

// Register the MC Code Emitter
TargetRegistry::RegisterMCCodeEmitter(TheHexagonTarget,
createHexagonMCCodeEmitter);
}
9 changes: 9 additions & 0 deletions llvm/lib/Target/Hexagon/MCTargetDesc/HexagonMCTargetDesc.h
Expand Up @@ -15,11 +15,20 @@
#define LLVM_LIB_TARGET_HEXAGON_MCTARGETDESC_HEXAGONMCTARGETDESC_H

namespace llvm {
class MCCodeEmitter;
class MCContext;
class MCInstrInfo;
class MCRegisterInfo;
class MCSubtargetInfo;
class Target;

extern Target TheHexagonTarget;

MCCodeEmitter *createHexagonMCCodeEmitter(const MCInstrInfo &MCII,
const MCRegisterInfo &MRI,
const MCSubtargetInfo &MST,
MCContext &MCT);

} // End llvm namespace

// Define symbolic names for Hexagon registers. This defines a mapping from
Expand Down
6 changes: 6 additions & 0 deletions llvm/unittests/MC/CMakeLists.txt
Expand Up @@ -7,3 +7,9 @@ add_llvm_unittest(MCTests
StringTableBuilderTest.cpp
YAMLTest.cpp
)

foreach(t ${LLVM_TARGETS_TO_BUILD})
if (IS_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/${t}")
add_subdirectory(${t})
endif (IS_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/${t}")
endforeach()

0 comments on commit 7da3f9a

Please sign in to comment.