You've already forked linux-packaging-mono
Imported Upstream version 5.18.0.167
Former-commit-id: 289509151e0fee68a1b591a20c9f109c3c789d3a
This commit is contained in:
parent
e19d552987
commit
b084638f15
@ -1,3 +0,0 @@
|
||||
add_llvm_library(LLVMPowerPCAsmParser
|
||||
PPCAsmParser.cpp
|
||||
)
|
@ -1,23 +0,0 @@
|
||||
;===- ./lib/Target/PowerPC/AsmParser/LLVMBuild.txt -------------*- Conf -*--===;
|
||||
;
|
||||
; The LLVM Compiler Infrastructure
|
||||
;
|
||||
; This file is distributed under the University of Illinois Open Source
|
||||
; License. See LICENSE.TXT for details.
|
||||
;
|
||||
;===------------------------------------------------------------------------===;
|
||||
;
|
||||
; This is an LLVMBuild description file for the components in this subdirectory.
|
||||
;
|
||||
; For more information on the LLVMBuild system, please see:
|
||||
;
|
||||
; http://llvm.org/docs/LLVMBuild.html
|
||||
;
|
||||
;===------------------------------------------------------------------------===;
|
||||
|
||||
[component_0]
|
||||
type = Library
|
||||
name = PowerPCAsmParser
|
||||
parent = PowerPC
|
||||
required_libraries = MC MCParser PowerPCDesc PowerPCInfo Support
|
||||
add_to_library_groups = PowerPC
|
File diff suppressed because it is too large
Load Diff
53
external/llvm/lib/Target/PowerPC/CMakeLists.txt
vendored
53
external/llvm/lib/Target/PowerPC/CMakeLists.txt
vendored
@ -1,53 +0,0 @@
|
||||
set(LLVM_TARGET_DEFINITIONS PPC.td)
|
||||
|
||||
tablegen(LLVM PPCGenAsmWriter.inc -gen-asm-writer)
|
||||
tablegen(LLVM PPCGenAsmMatcher.inc -gen-asm-matcher)
|
||||
tablegen(LLVM PPCGenDisassemblerTables.inc -gen-disassembler)
|
||||
tablegen(LLVM PPCGenMCCodeEmitter.inc -gen-emitter)
|
||||
tablegen(LLVM PPCGenRegisterInfo.inc -gen-register-info)
|
||||
tablegen(LLVM PPCGenInstrInfo.inc -gen-instr-info)
|
||||
tablegen(LLVM PPCGenDAGISel.inc -gen-dag-isel)
|
||||
tablegen(LLVM PPCGenFastISel.inc -gen-fast-isel)
|
||||
tablegen(LLVM PPCGenCallingConv.inc -gen-callingconv)
|
||||
tablegen(LLVM PPCGenSubtargetInfo.inc -gen-subtarget)
|
||||
add_public_tablegen_target(PowerPCCommonTableGen)
|
||||
|
||||
add_llvm_target(PowerPCCodeGen
|
||||
PPCBoolRetToInt.cpp
|
||||
PPCAsmPrinter.cpp
|
||||
PPCBranchSelector.cpp
|
||||
PPCBranchCoalescing.cpp
|
||||
PPCCCState.cpp
|
||||
PPCCTRLoops.cpp
|
||||
PPCHazardRecognizers.cpp
|
||||
PPCInstrInfo.cpp
|
||||
PPCISelDAGToDAG.cpp
|
||||
PPCISelLowering.cpp
|
||||
PPCEarlyReturn.cpp
|
||||
PPCFastISel.cpp
|
||||
PPCFrameLowering.cpp
|
||||
PPCLoopPreIncPrep.cpp
|
||||
PPCMCInstLower.cpp
|
||||
PPCMachineFunctionInfo.cpp
|
||||
PPCMIPeephole.cpp
|
||||
PPCRegisterInfo.cpp
|
||||
PPCQPXLoadSplat.cpp
|
||||
PPCSubtarget.cpp
|
||||
PPCTargetMachine.cpp
|
||||
PPCTargetObjectFile.cpp
|
||||
PPCTargetTransformInfo.cpp
|
||||
PPCTOCRegDeps.cpp
|
||||
PPCTLSDynamicCall.cpp
|
||||
PPCVSXCopy.cpp
|
||||
PPCReduceCRLogicals.cpp
|
||||
PPCVSXFMAMutate.cpp
|
||||
PPCVSXSwapRemoval.cpp
|
||||
PPCExpandISEL.cpp
|
||||
PPCPreEmitPeephole.cpp
|
||||
)
|
||||
|
||||
add_subdirectory(AsmParser)
|
||||
add_subdirectory(Disassembler)
|
||||
add_subdirectory(InstPrinter)
|
||||
add_subdirectory(TargetInfo)
|
||||
add_subdirectory(MCTargetDesc)
|
@ -1,3 +0,0 @@
|
||||
add_llvm_library(LLVMPowerPCDisassembler
|
||||
PPCDisassembler.cpp
|
||||
)
|
@ -1,23 +0,0 @@
|
||||
;===-- ./lib/Target/PowerPC/Disassembler/LLVMBuild.txt ---------*- Conf -*--===;
|
||||
;
|
||||
; The LLVM Compiler Infrastructure
|
||||
;
|
||||
; This file is distributed under the University of Illinois Open Source
|
||||
; License. See LICENSE.TXT for details.
|
||||
;
|
||||
;===------------------------------------------------------------------------===;
|
||||
;
|
||||
; This is an LLVMBuild description file for the components in this subdirectory.
|
||||
;
|
||||
; For more information on the LLVMBuild system, please see:
|
||||
;
|
||||
; http://llvm.org/docs/LLVMBuild.html
|
||||
;
|
||||
;===------------------------------------------------------------------------===;
|
||||
|
||||
[component_0]
|
||||
type = Library
|
||||
name = PowerPCDisassembler
|
||||
parent = PowerPC
|
||||
required_libraries = MCDisassembler PowerPCInfo Support
|
||||
add_to_library_groups = PowerPC
|
@ -1,457 +0,0 @@
|
||||
//===------ PPCDisassembler.cpp - Disassembler for PowerPC ------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "PPC.h"
|
||||
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
|
||||
#include "llvm/MC/MCFixedLenDisassembler.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/MC/MCSubtargetInfo.h"
|
||||
#include "llvm/Support/Endian.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "ppc-disassembler"
|
||||
|
||||
typedef MCDisassembler::DecodeStatus DecodeStatus;
|
||||
|
||||
namespace {
|
||||
class PPCDisassembler : public MCDisassembler {
|
||||
bool IsLittleEndian;
|
||||
|
||||
public:
|
||||
PPCDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
|
||||
bool IsLittleEndian)
|
||||
: MCDisassembler(STI, Ctx), IsLittleEndian(IsLittleEndian) {}
|
||||
|
||||
DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
|
||||
ArrayRef<uint8_t> Bytes, uint64_t Address,
|
||||
raw_ostream &VStream,
|
||||
raw_ostream &CStream) const override;
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
static MCDisassembler *createPPCDisassembler(const Target &T,
|
||||
const MCSubtargetInfo &STI,
|
||||
MCContext &Ctx) {
|
||||
return new PPCDisassembler(STI, Ctx, /*IsLittleEndian=*/false);
|
||||
}
|
||||
|
||||
static MCDisassembler *createPPCLEDisassembler(const Target &T,
|
||||
const MCSubtargetInfo &STI,
|
||||
MCContext &Ctx) {
|
||||
return new PPCDisassembler(STI, Ctx, /*IsLittleEndian=*/true);
|
||||
}
|
||||
|
||||
extern "C" void LLVMInitializePowerPCDisassembler() {
|
||||
// Register the disassembler for each target.
|
||||
TargetRegistry::RegisterMCDisassembler(getThePPC32Target(),
|
||||
createPPCDisassembler);
|
||||
TargetRegistry::RegisterMCDisassembler(getThePPC64Target(),
|
||||
createPPCDisassembler);
|
||||
TargetRegistry::RegisterMCDisassembler(getThePPC64LETarget(),
|
||||
createPPCLEDisassembler);
|
||||
}
|
||||
|
||||
// FIXME: These can be generated by TableGen from the existing register
|
||||
// encoding values!
|
||||
|
||||
static const unsigned CRRegs[] = {
|
||||
PPC::CR0, PPC::CR1, PPC::CR2, PPC::CR3,
|
||||
PPC::CR4, PPC::CR5, PPC::CR6, PPC::CR7
|
||||
};
|
||||
|
||||
static const unsigned CRBITRegs[] = {
|
||||
PPC::CR0LT, PPC::CR0GT, PPC::CR0EQ, PPC::CR0UN,
|
||||
PPC::CR1LT, PPC::CR1GT, PPC::CR1EQ, PPC::CR1UN,
|
||||
PPC::CR2LT, PPC::CR2GT, PPC::CR2EQ, PPC::CR2UN,
|
||||
PPC::CR3LT, PPC::CR3GT, PPC::CR3EQ, PPC::CR3UN,
|
||||
PPC::CR4LT, PPC::CR4GT, PPC::CR4EQ, PPC::CR4UN,
|
||||
PPC::CR5LT, PPC::CR5GT, PPC::CR5EQ, PPC::CR5UN,
|
||||
PPC::CR6LT, PPC::CR6GT, PPC::CR6EQ, PPC::CR6UN,
|
||||
PPC::CR7LT, PPC::CR7GT, PPC::CR7EQ, PPC::CR7UN
|
||||
};
|
||||
|
||||
static const unsigned FRegs[] = {
|
||||
PPC::F0, PPC::F1, PPC::F2, PPC::F3,
|
||||
PPC::F4, PPC::F5, PPC::F6, PPC::F7,
|
||||
PPC::F8, PPC::F9, PPC::F10, PPC::F11,
|
||||
PPC::F12, PPC::F13, PPC::F14, PPC::F15,
|
||||
PPC::F16, PPC::F17, PPC::F18, PPC::F19,
|
||||
PPC::F20, PPC::F21, PPC::F22, PPC::F23,
|
||||
PPC::F24, PPC::F25, PPC::F26, PPC::F27,
|
||||
PPC::F28, PPC::F29, PPC::F30, PPC::F31
|
||||
};
|
||||
|
||||
static const unsigned VFRegs[] = {
|
||||
PPC::VF0, PPC::VF1, PPC::VF2, PPC::VF3,
|
||||
PPC::VF4, PPC::VF5, PPC::VF6, PPC::VF7,
|
||||
PPC::VF8, PPC::VF9, PPC::VF10, PPC::VF11,
|
||||
PPC::VF12, PPC::VF13, PPC::VF14, PPC::VF15,
|
||||
PPC::VF16, PPC::VF17, PPC::VF18, PPC::VF19,
|
||||
PPC::VF20, PPC::VF21, PPC::VF22, PPC::VF23,
|
||||
PPC::VF24, PPC::VF25, PPC::VF26, PPC::VF27,
|
||||
PPC::VF28, PPC::VF29, PPC::VF30, PPC::VF31
|
||||
};
|
||||
|
||||
static const unsigned VRegs[] = {
|
||||
PPC::V0, PPC::V1, PPC::V2, PPC::V3,
|
||||
PPC::V4, PPC::V5, PPC::V6, PPC::V7,
|
||||
PPC::V8, PPC::V9, PPC::V10, PPC::V11,
|
||||
PPC::V12, PPC::V13, PPC::V14, PPC::V15,
|
||||
PPC::V16, PPC::V17, PPC::V18, PPC::V19,
|
||||
PPC::V20, PPC::V21, PPC::V22, PPC::V23,
|
||||
PPC::V24, PPC::V25, PPC::V26, PPC::V27,
|
||||
PPC::V28, PPC::V29, PPC::V30, PPC::V31
|
||||
};
|
||||
|
||||
static const unsigned VSRegs[] = {
|
||||
PPC::VSL0, PPC::VSL1, PPC::VSL2, PPC::VSL3,
|
||||
PPC::VSL4, PPC::VSL5, PPC::VSL6, PPC::VSL7,
|
||||
PPC::VSL8, PPC::VSL9, PPC::VSL10, PPC::VSL11,
|
||||
PPC::VSL12, PPC::VSL13, PPC::VSL14, PPC::VSL15,
|
||||
PPC::VSL16, PPC::VSL17, PPC::VSL18, PPC::VSL19,
|
||||
PPC::VSL20, PPC::VSL21, PPC::VSL22, PPC::VSL23,
|
||||
PPC::VSL24, PPC::VSL25, PPC::VSL26, PPC::VSL27,
|
||||
PPC::VSL28, PPC::VSL29, PPC::VSL30, PPC::VSL31,
|
||||
|
||||
PPC::V0, PPC::V1, PPC::V2, PPC::V3,
|
||||
PPC::V4, PPC::V5, PPC::V6, PPC::V7,
|
||||
PPC::V8, PPC::V9, PPC::V10, PPC::V11,
|
||||
PPC::V12, PPC::V13, PPC::V14, PPC::V15,
|
||||
PPC::V16, PPC::V17, PPC::V18, PPC::V19,
|
||||
PPC::V20, PPC::V21, PPC::V22, PPC::V23,
|
||||
PPC::V24, PPC::V25, PPC::V26, PPC::V27,
|
||||
PPC::V28, PPC::V29, PPC::V30, PPC::V31
|
||||
};
|
||||
|
||||
static const unsigned VSFRegs[] = {
|
||||
PPC::F0, PPC::F1, PPC::F2, PPC::F3,
|
||||
PPC::F4, PPC::F5, PPC::F6, PPC::F7,
|
||||
PPC::F8, PPC::F9, PPC::F10, PPC::F11,
|
||||
PPC::F12, PPC::F13, PPC::F14, PPC::F15,
|
||||
PPC::F16, PPC::F17, PPC::F18, PPC::F19,
|
||||
PPC::F20, PPC::F21, PPC::F22, PPC::F23,
|
||||
PPC::F24, PPC::F25, PPC::F26, PPC::F27,
|
||||
PPC::F28, PPC::F29, PPC::F30, PPC::F31,
|
||||
|
||||
PPC::VF0, PPC::VF1, PPC::VF2, PPC::VF3,
|
||||
PPC::VF4, PPC::VF5, PPC::VF6, PPC::VF7,
|
||||
PPC::VF8, PPC::VF9, PPC::VF10, PPC::VF11,
|
||||
PPC::VF12, PPC::VF13, PPC::VF14, PPC::VF15,
|
||||
PPC::VF16, PPC::VF17, PPC::VF18, PPC::VF19,
|
||||
PPC::VF20, PPC::VF21, PPC::VF22, PPC::VF23,
|
||||
PPC::VF24, PPC::VF25, PPC::VF26, PPC::VF27,
|
||||
PPC::VF28, PPC::VF29, PPC::VF30, PPC::VF31
|
||||
};
|
||||
|
||||
static const unsigned VSSRegs[] = {
|
||||
PPC::F0, PPC::F1, PPC::F2, PPC::F3,
|
||||
PPC::F4, PPC::F5, PPC::F6, PPC::F7,
|
||||
PPC::F8, PPC::F9, PPC::F10, PPC::F11,
|
||||
PPC::F12, PPC::F13, PPC::F14, PPC::F15,
|
||||
PPC::F16, PPC::F17, PPC::F18, PPC::F19,
|
||||
PPC::F20, PPC::F21, PPC::F22, PPC::F23,
|
||||
PPC::F24, PPC::F25, PPC::F26, PPC::F27,
|
||||
PPC::F28, PPC::F29, PPC::F30, PPC::F31,
|
||||
|
||||
PPC::VF0, PPC::VF1, PPC::VF2, PPC::VF3,
|
||||
PPC::VF4, PPC::VF5, PPC::VF6, PPC::VF7,
|
||||
PPC::VF8, PPC::VF9, PPC::VF10, PPC::VF11,
|
||||
PPC::VF12, PPC::VF13, PPC::VF14, PPC::VF15,
|
||||
PPC::VF16, PPC::VF17, PPC::VF18, PPC::VF19,
|
||||
PPC::VF20, PPC::VF21, PPC::VF22, PPC::VF23,
|
||||
PPC::VF24, PPC::VF25, PPC::VF26, PPC::VF27,
|
||||
PPC::VF28, PPC::VF29, PPC::VF30, PPC::VF31
|
||||
};
|
||||
|
||||
static const unsigned GPRegs[] = {
|
||||
PPC::R0, PPC::R1, PPC::R2, PPC::R3,
|
||||
PPC::R4, PPC::R5, PPC::R6, PPC::R7,
|
||||
PPC::R8, PPC::R9, PPC::R10, PPC::R11,
|
||||
PPC::R12, PPC::R13, PPC::R14, PPC::R15,
|
||||
PPC::R16, PPC::R17, PPC::R18, PPC::R19,
|
||||
PPC::R20, PPC::R21, PPC::R22, PPC::R23,
|
||||
PPC::R24, PPC::R25, PPC::R26, PPC::R27,
|
||||
PPC::R28, PPC::R29, PPC::R30, PPC::R31
|
||||
};
|
||||
|
||||
static const unsigned GP0Regs[] = {
|
||||
PPC::ZERO, PPC::R1, PPC::R2, PPC::R3,
|
||||
PPC::R4, PPC::R5, PPC::R6, PPC::R7,
|
||||
PPC::R8, PPC::R9, PPC::R10, PPC::R11,
|
||||
PPC::R12, PPC::R13, PPC::R14, PPC::R15,
|
||||
PPC::R16, PPC::R17, PPC::R18, PPC::R19,
|
||||
PPC::R20, PPC::R21, PPC::R22, PPC::R23,
|
||||
PPC::R24, PPC::R25, PPC::R26, PPC::R27,
|
||||
PPC::R28, PPC::R29, PPC::R30, PPC::R31
|
||||
};
|
||||
|
||||
static const unsigned G8Regs[] = {
|
||||
PPC::X0, PPC::X1, PPC::X2, PPC::X3,
|
||||
PPC::X4, PPC::X5, PPC::X6, PPC::X7,
|
||||
PPC::X8, PPC::X9, PPC::X10, PPC::X11,
|
||||
PPC::X12, PPC::X13, PPC::X14, PPC::X15,
|
||||
PPC::X16, PPC::X17, PPC::X18, PPC::X19,
|
||||
PPC::X20, PPC::X21, PPC::X22, PPC::X23,
|
||||
PPC::X24, PPC::X25, PPC::X26, PPC::X27,
|
||||
PPC::X28, PPC::X29, PPC::X30, PPC::X31
|
||||
};
|
||||
|
||||
static const unsigned G80Regs[] = {
|
||||
PPC::ZERO8, PPC::X1, PPC::X2, PPC::X3,
|
||||
PPC::X4, PPC::X5, PPC::X6, PPC::X7,
|
||||
PPC::X8, PPC::X9, PPC::X10, PPC::X11,
|
||||
PPC::X12, PPC::X13, PPC::X14, PPC::X15,
|
||||
PPC::X16, PPC::X17, PPC::X18, PPC::X19,
|
||||
PPC::X20, PPC::X21, PPC::X22, PPC::X23,
|
||||
PPC::X24, PPC::X25, PPC::X26, PPC::X27,
|
||||
PPC::X28, PPC::X29, PPC::X30, PPC::X31
|
||||
};
|
||||
|
||||
static const unsigned QFRegs[] = {
|
||||
PPC::QF0, PPC::QF1, PPC::QF2, PPC::QF3,
|
||||
PPC::QF4, PPC::QF5, PPC::QF6, PPC::QF7,
|
||||
PPC::QF8, PPC::QF9, PPC::QF10, PPC::QF11,
|
||||
PPC::QF12, PPC::QF13, PPC::QF14, PPC::QF15,
|
||||
PPC::QF16, PPC::QF17, PPC::QF18, PPC::QF19,
|
||||
PPC::QF20, PPC::QF21, PPC::QF22, PPC::QF23,
|
||||
PPC::QF24, PPC::QF25, PPC::QF26, PPC::QF27,
|
||||
PPC::QF28, PPC::QF29, PPC::QF30, PPC::QF31
|
||||
};
|
||||
|
||||
template <std::size_t N>
|
||||
static DecodeStatus decodeRegisterClass(MCInst &Inst, uint64_t RegNo,
|
||||
const unsigned (&Regs)[N]) {
|
||||
assert(RegNo < N && "Invalid register number");
|
||||
Inst.addOperand(MCOperand::createReg(Regs[RegNo]));
|
||||
return MCDisassembler::Success;
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeCRRCRegisterClass(MCInst &Inst, uint64_t RegNo,
|
||||
uint64_t Address,
|
||||
const void *Decoder) {
|
||||
return decodeRegisterClass(Inst, RegNo, CRRegs);
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeCRRC0RegisterClass(MCInst &Inst, uint64_t RegNo,
|
||||
uint64_t Address,
|
||||
const void *Decoder) {
|
||||
return decodeRegisterClass(Inst, RegNo, CRRegs);
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeCRBITRCRegisterClass(MCInst &Inst, uint64_t RegNo,
|
||||
uint64_t Address,
|
||||
const void *Decoder) {
|
||||
return decodeRegisterClass(Inst, RegNo, CRBITRegs);
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeF4RCRegisterClass(MCInst &Inst, uint64_t RegNo,
|
||||
uint64_t Address,
|
||||
const void *Decoder) {
|
||||
return decodeRegisterClass(Inst, RegNo, FRegs);
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeF8RCRegisterClass(MCInst &Inst, uint64_t RegNo,
|
||||
uint64_t Address,
|
||||
const void *Decoder) {
|
||||
return decodeRegisterClass(Inst, RegNo, FRegs);
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeVFRCRegisterClass(MCInst &Inst, uint64_t RegNo,
|
||||
uint64_t Address,
|
||||
const void *Decoder) {
|
||||
return decodeRegisterClass(Inst, RegNo, VFRegs);
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeVRRCRegisterClass(MCInst &Inst, uint64_t RegNo,
|
||||
uint64_t Address,
|
||||
const void *Decoder) {
|
||||
return decodeRegisterClass(Inst, RegNo, VRegs);
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeVSRCRegisterClass(MCInst &Inst, uint64_t RegNo,
|
||||
uint64_t Address,
|
||||
const void *Decoder) {
|
||||
return decodeRegisterClass(Inst, RegNo, VSRegs);
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeVSFRCRegisterClass(MCInst &Inst, uint64_t RegNo,
|
||||
uint64_t Address,
|
||||
const void *Decoder) {
|
||||
return decodeRegisterClass(Inst, RegNo, VSFRegs);
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeVSSRCRegisterClass(MCInst &Inst, uint64_t RegNo,
|
||||
uint64_t Address,
|
||||
const void *Decoder) {
|
||||
return decodeRegisterClass(Inst, RegNo, VSSRegs);
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeGPRCRegisterClass(MCInst &Inst, uint64_t RegNo,
|
||||
uint64_t Address,
|
||||
const void *Decoder) {
|
||||
return decodeRegisterClass(Inst, RegNo, GPRegs);
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeGPRC_NOR0RegisterClass(MCInst &Inst, uint64_t RegNo,
|
||||
uint64_t Address,
|
||||
const void *Decoder) {
|
||||
return decodeRegisterClass(Inst, RegNo, GP0Regs);
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeG8RCRegisterClass(MCInst &Inst, uint64_t RegNo,
|
||||
uint64_t Address,
|
||||
const void *Decoder) {
|
||||
return decodeRegisterClass(Inst, RegNo, G8Regs);
|
||||
}
|
||||
|
||||
static DecodeStatus DecodeG8RC_NOX0RegisterClass(MCInst &Inst, uint64_t RegNo,
|
||||
uint64_t Address,
|
||||
const void *Decoder) {
|
||||
return decodeRegisterClass(Inst, RegNo, G80Regs);
|
||||
}
|
||||
|
||||
#define DecodePointerLikeRegClass0 DecodeGPRCRegisterClass
|
||||
#define DecodePointerLikeRegClass1 DecodeGPRC_NOR0RegisterClass
|
||||
|
||||
static DecodeStatus DecodeQFRCRegisterClass(MCInst &Inst, uint64_t RegNo,
|
||||
uint64_t Address,
|
||||
const void *Decoder) {
|
||||
return decodeRegisterClass(Inst, RegNo, QFRegs);
|
||||
}
|
||||
|
||||
#define DecodeQSRCRegisterClass DecodeQFRCRegisterClass
|
||||
#define DecodeQBRCRegisterClass DecodeQFRCRegisterClass
|
||||
|
||||
template<unsigned N>
|
||||
static DecodeStatus decodeUImmOperand(MCInst &Inst, uint64_t Imm,
|
||||
int64_t Address, const void *Decoder) {
|
||||
assert(isUInt<N>(Imm) && "Invalid immediate");
|
||||
Inst.addOperand(MCOperand::createImm(Imm));
|
||||
return MCDisassembler::Success;
|
||||
}
|
||||
|
||||
template<unsigned N>
|
||||
static DecodeStatus decodeSImmOperand(MCInst &Inst, uint64_t Imm,
|
||||
int64_t Address, const void *Decoder) {
|
||||
assert(isUInt<N>(Imm) && "Invalid immediate");
|
||||
Inst.addOperand(MCOperand::createImm(SignExtend64<N>(Imm)));
|
||||
return MCDisassembler::Success;
|
||||
}
|
||||
|
||||
static DecodeStatus decodeMemRIOperands(MCInst &Inst, uint64_t Imm,
|
||||
int64_t Address, const void *Decoder) {
|
||||
// Decode the memri field (imm, reg), which has the low 16-bits as the
|
||||
// displacement and the next 5 bits as the register #.
|
||||
|
||||
uint64_t Base = Imm >> 16;
|
||||
uint64_t Disp = Imm & 0xFFFF;
|
||||
|
||||
assert(Base < 32 && "Invalid base register");
|
||||
|
||||
switch (Inst.getOpcode()) {
|
||||
default: break;
|
||||
case PPC::LBZU:
|
||||
case PPC::LHAU:
|
||||
case PPC::LHZU:
|
||||
case PPC::LWZU:
|
||||
case PPC::LFSU:
|
||||
case PPC::LFDU:
|
||||
// Add the tied output operand.
|
||||
Inst.addOperand(MCOperand::createReg(GP0Regs[Base]));
|
||||
break;
|
||||
case PPC::STBU:
|
||||
case PPC::STHU:
|
||||
case PPC::STWU:
|
||||
case PPC::STFSU:
|
||||
case PPC::STFDU:
|
||||
Inst.insert(Inst.begin(), MCOperand::createReg(GP0Regs[Base]));
|
||||
break;
|
||||
}
|
||||
|
||||
Inst.addOperand(MCOperand::createImm(SignExtend64<16>(Disp)));
|
||||
Inst.addOperand(MCOperand::createReg(GP0Regs[Base]));
|
||||
return MCDisassembler::Success;
|
||||
}
|
||||
|
||||
static DecodeStatus decodeMemRIXOperands(MCInst &Inst, uint64_t Imm,
|
||||
int64_t Address, const void *Decoder) {
|
||||
// Decode the memrix field (imm, reg), which has the low 14-bits as the
|
||||
// displacement and the next 5 bits as the register #.
|
||||
|
||||
uint64_t Base = Imm >> 14;
|
||||
uint64_t Disp = Imm & 0x3FFF;
|
||||
|
||||
assert(Base < 32 && "Invalid base register");
|
||||
|
||||
if (Inst.getOpcode() == PPC::LDU)
|
||||
// Add the tied output operand.
|
||||
Inst.addOperand(MCOperand::createReg(GP0Regs[Base]));
|
||||
else if (Inst.getOpcode() == PPC::STDU)
|
||||
Inst.insert(Inst.begin(), MCOperand::createReg(GP0Regs[Base]));
|
||||
|
||||
Inst.addOperand(MCOperand::createImm(SignExtend64<16>(Disp << 2)));
|
||||
Inst.addOperand(MCOperand::createReg(GP0Regs[Base]));
|
||||
return MCDisassembler::Success;
|
||||
}
|
||||
|
||||
static DecodeStatus decodeMemRIX16Operands(MCInst &Inst, uint64_t Imm,
|
||||
int64_t Address, const void *Decoder) {
|
||||
// Decode the memrix16 field (imm, reg), which has the low 12-bits as the
|
||||
// displacement with 16-byte aligned, and the next 5 bits as the register #.
|
||||
|
||||
uint64_t Base = Imm >> 12;
|
||||
uint64_t Disp = Imm & 0xFFF;
|
||||
|
||||
assert(Base < 32 && "Invalid base register");
|
||||
|
||||
Inst.addOperand(MCOperand::createImm(SignExtend64<16>(Disp << 4)));
|
||||
Inst.addOperand(MCOperand::createReg(GP0Regs[Base]));
|
||||
return MCDisassembler::Success;
|
||||
}
|
||||
|
||||
static DecodeStatus decodeCRBitMOperand(MCInst &Inst, uint64_t Imm,
|
||||
int64_t Address, const void *Decoder) {
|
||||
// The cr bit encoding is 0x80 >> cr_reg_num.
|
||||
|
||||
unsigned Zeros = countTrailingZeros(Imm);
|
||||
assert(Zeros < 8 && "Invalid CR bit value");
|
||||
|
||||
Inst.addOperand(MCOperand::createReg(CRRegs[7 - Zeros]));
|
||||
return MCDisassembler::Success;
|
||||
}
|
||||
|
||||
#include "PPCGenDisassemblerTables.inc"
|
||||
|
||||
DecodeStatus PPCDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
|
||||
ArrayRef<uint8_t> Bytes,
|
||||
uint64_t Address, raw_ostream &OS,
|
||||
raw_ostream &CS) const {
|
||||
// Get the four bytes of the instruction.
|
||||
Size = 4;
|
||||
if (Bytes.size() < 4) {
|
||||
Size = 0;
|
||||
return MCDisassembler::Fail;
|
||||
}
|
||||
|
||||
// Read the instruction in the proper endianness.
|
||||
uint32_t Inst = IsLittleEndian ? support::endian::read32le(Bytes.data())
|
||||
: support::endian::read32be(Bytes.data());
|
||||
|
||||
if (STI.getFeatureBits()[PPC::FeatureQPX]) {
|
||||
DecodeStatus result =
|
||||
decodeInstruction(DecoderTableQPX32, MI, Inst, Address, this, STI);
|
||||
if (result != MCDisassembler::Fail)
|
||||
return result;
|
||||
}
|
||||
|
||||
return decodeInstruction(DecoderTable32, MI, Inst, Address, this, STI);
|
||||
}
|
||||
|
@ -1,3 +0,0 @@
|
||||
add_llvm_library(LLVMPowerPCAsmPrinter
|
||||
PPCInstPrinter.cpp
|
||||
)
|
@ -1,23 +0,0 @@
|
||||
;===- ./lib/Target/PowerPC/InstPrinter/LLVMBuild.txt -----------*- Conf -*--===;
|
||||
;
|
||||
; The LLVM Compiler Infrastructure
|
||||
;
|
||||
; This file is distributed under the University of Illinois Open Source
|
||||
; License. See LICENSE.TXT for details.
|
||||
;
|
||||
;===------------------------------------------------------------------------===;
|
||||
;
|
||||
; This is an LLVMBuild description file for the components in this subdirectory.
|
||||
;
|
||||
; For more information on the LLVMBuild system, please see:
|
||||
;
|
||||
; http://llvm.org/docs/LLVMBuild.html
|
||||
;
|
||||
;===------------------------------------------------------------------------===;
|
||||
|
||||
[component_0]
|
||||
type = Library
|
||||
name = PowerPCAsmPrinter
|
||||
parent = PowerPC
|
||||
required_libraries = MC Support
|
||||
add_to_library_groups = PowerPC
|
File diff suppressed because it is too large
Load Diff
@ -1,77 +0,0 @@
|
||||
//===- PPCInstPrinter.h - Convert PPC MCInst to assembly syntax -*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This class prints an PPC MCInst to a .s file.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIB_TARGET_POWERPC_INSTPRINTER_PPCINSTPRINTER_H
|
||||
#define LLVM_LIB_TARGET_POWERPC_INSTPRINTER_PPCINSTPRINTER_H
|
||||
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/MC/MCInstPrinter.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class PPCInstPrinter : public MCInstPrinter {
|
||||
Triple TT;
|
||||
private:
|
||||
bool showRegistersWithPercentPrefix(const char *RegName) const;
|
||||
bool showRegistersWithPrefix() const;
|
||||
const char *getVerboseConditionRegName(unsigned RegNum,
|
||||
unsigned RegEncoding) const;
|
||||
|
||||
public:
|
||||
PPCInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
|
||||
const MCRegisterInfo &MRI, Triple T)
|
||||
: MCInstPrinter(MAI, MII, MRI), TT(T) {}
|
||||
|
||||
void printRegName(raw_ostream &OS, unsigned RegNo) const override;
|
||||
void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot,
|
||||
const MCSubtargetInfo &STI) override;
|
||||
|
||||
// Autogenerated by tblgen.
|
||||
void printInstruction(const MCInst *MI, raw_ostream &O);
|
||||
static const char *getRegisterName(unsigned RegNo);
|
||||
|
||||
bool printAliasInstr(const MCInst *MI, raw_ostream &OS);
|
||||
void printCustomAliasOperand(const MCInst *MI, unsigned OpIdx,
|
||||
unsigned PrintMethodIdx,
|
||||
raw_ostream &OS);
|
||||
|
||||
void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
void printPredicateOperand(const MCInst *MI, unsigned OpNo,
|
||||
raw_ostream &O, const char *Modifier = nullptr);
|
||||
void printATBitsAsHint(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
|
||||
void printU1ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
void printU2ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
void printU3ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
void printU4ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
void printS5ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
void printU5ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
void printU6ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
void printU7ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
void printU8ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
void printU10ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
void printU12ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
void printS16ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
void printU16ImmOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
void printBranchOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
void printAbsBranchOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
void printTLSCall(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
|
||||
void printcrbitm(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
|
||||
void printMemRegImm(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
void printMemRegReg(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
};
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
35
external/llvm/lib/Target/PowerPC/LLVMBuild.txt
vendored
35
external/llvm/lib/Target/PowerPC/LLVMBuild.txt
vendored
@ -1,35 +0,0 @@
|
||||
;===- ./lib/Target/PowerPC/LLVMBuild.txt -----------------------*- Conf -*--===;
|
||||
;
|
||||
; The LLVM Compiler Infrastructure
|
||||
;
|
||||
; This file is distributed under the University of Illinois Open Source
|
||||
; License. See LICENSE.TXT for details.
|
||||
;
|
||||
;===------------------------------------------------------------------------===;
|
||||
;
|
||||
; This is an LLVMBuild description file for the components in this subdirectory.
|
||||
;
|
||||
; For more information on the LLVMBuild system, please see:
|
||||
;
|
||||
; http://llvm.org/docs/LLVMBuild.html
|
||||
;
|
||||
;===------------------------------------------------------------------------===;
|
||||
|
||||
[common]
|
||||
subdirectories = AsmParser Disassembler InstPrinter MCTargetDesc TargetInfo
|
||||
|
||||
[component_0]
|
||||
type = TargetGroup
|
||||
name = PowerPC
|
||||
parent = Target
|
||||
has_asmparser = 1
|
||||
has_asmprinter = 1
|
||||
has_disassembler = 1
|
||||
has_jit = 1
|
||||
|
||||
[component_1]
|
||||
type = Library
|
||||
name = PowerPCCodeGen
|
||||
parent = PowerPC
|
||||
required_libraries = Analysis AsmPrinter CodeGen Core MC PowerPCAsmPrinter PowerPCDesc PowerPCInfo Scalar SelectionDAG Support Target TransformUtils
|
||||
add_to_library_groups = PowerPC
|
@ -1,10 +0,0 @@
|
||||
add_llvm_library(LLVMPowerPCDesc
|
||||
PPCAsmBackend.cpp
|
||||
PPCMCTargetDesc.cpp
|
||||
PPCMCAsmInfo.cpp
|
||||
PPCMCCodeEmitter.cpp
|
||||
PPCMCExpr.cpp
|
||||
PPCPredicates.cpp
|
||||
PPCMachObjectWriter.cpp
|
||||
PPCELFObjectWriter.cpp
|
||||
)
|
@ -1,23 +0,0 @@
|
||||
;===- ./lib/Target/PowerPC/MCTargetDesc/LLVMBuild.txt ----------*- Conf -*--===;
|
||||
;
|
||||
; The LLVM Compiler Infrastructure
|
||||
;
|
||||
; This file is distributed under the University of Illinois Open Source
|
||||
; License. See LICENSE.TXT for details.
|
||||
;
|
||||
;===------------------------------------------------------------------------===;
|
||||
;
|
||||
; This is an LLVMBuild description file for the components in this subdirectory.
|
||||
;
|
||||
; For more information on the LLVMBuild system, please see:
|
||||
;
|
||||
; http://llvm.org/docs/LLVMBuild.html
|
||||
;
|
||||
;===------------------------------------------------------------------------===;
|
||||
|
||||
[component_0]
|
||||
type = Library
|
||||
name = PowerPCDesc
|
||||
parent = PowerPC
|
||||
required_libraries = MC PowerPCAsmPrinter PowerPCInfo Support
|
||||
add_to_library_groups = PowerPC
|
@ -1,245 +0,0 @@
|
||||
//===-- PPCAsmBackend.cpp - PPC Assembler Backend -------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "MCTargetDesc/PPCFixupKinds.h"
|
||||
#include "MCTargetDesc/PPCMCTargetDesc.h"
|
||||
#include "llvm/BinaryFormat/ELF.h"
|
||||
#include "llvm/BinaryFormat/MachO.h"
|
||||
#include "llvm/MC/MCAsmBackend.h"
|
||||
#include "llvm/MC/MCAssembler.h"
|
||||
#include "llvm/MC/MCELFObjectWriter.h"
|
||||
#include "llvm/MC/MCFixupKindInfo.h"
|
||||
#include "llvm/MC/MCMachObjectWriter.h"
|
||||
#include "llvm/MC/MCObjectWriter.h"
|
||||
#include "llvm/MC/MCSectionMachO.h"
|
||||
#include "llvm/MC/MCSubtargetInfo.h"
|
||||
#include "llvm/MC/MCSymbolELF.h"
|
||||
#include "llvm/MC/MCValue.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
using namespace llvm;
|
||||
|
||||
static uint64_t adjustFixupValue(unsigned Kind, uint64_t Value) {
|
||||
switch (Kind) {
|
||||
default:
|
||||
llvm_unreachable("Unknown fixup kind!");
|
||||
case FK_Data_1:
|
||||
case FK_Data_2:
|
||||
case FK_Data_4:
|
||||
case FK_Data_8:
|
||||
case PPC::fixup_ppc_nofixup:
|
||||
return Value;
|
||||
case PPC::fixup_ppc_brcond14:
|
||||
case PPC::fixup_ppc_brcond14abs:
|
||||
return Value & 0xfffc;
|
||||
case PPC::fixup_ppc_br24:
|
||||
case PPC::fixup_ppc_br24abs:
|
||||
return Value & 0x3fffffc;
|
||||
case PPC::fixup_ppc_half16:
|
||||
return Value & 0xffff;
|
||||
case PPC::fixup_ppc_half16ds:
|
||||
return Value & 0xfffc;
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned getFixupKindNumBytes(unsigned Kind) {
|
||||
switch (Kind) {
|
||||
default:
|
||||
llvm_unreachable("Unknown fixup kind!");
|
||||
case FK_Data_1:
|
||||
return 1;
|
||||
case FK_Data_2:
|
||||
case PPC::fixup_ppc_half16:
|
||||
case PPC::fixup_ppc_half16ds:
|
||||
return 2;
|
||||
case FK_Data_4:
|
||||
case PPC::fixup_ppc_brcond14:
|
||||
case PPC::fixup_ppc_brcond14abs:
|
||||
case PPC::fixup_ppc_br24:
|
||||
case PPC::fixup_ppc_br24abs:
|
||||
return 4;
|
||||
case FK_Data_8:
|
||||
return 8;
|
||||
case PPC::fixup_ppc_nofixup:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class PPCAsmBackend : public MCAsmBackend {
|
||||
const Target &TheTarget;
|
||||
bool IsLittleEndian;
|
||||
public:
|
||||
PPCAsmBackend(const Target &T, bool isLittle) : MCAsmBackend(), TheTarget(T),
|
||||
IsLittleEndian(isLittle) {}
|
||||
|
||||
unsigned getNumFixupKinds() const override {
|
||||
return PPC::NumTargetFixupKinds;
|
||||
}
|
||||
|
||||
const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override {
|
||||
const static MCFixupKindInfo InfosBE[PPC::NumTargetFixupKinds] = {
|
||||
// name offset bits flags
|
||||
{ "fixup_ppc_br24", 6, 24, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_ppc_brcond14", 16, 14, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_ppc_br24abs", 6, 24, 0 },
|
||||
{ "fixup_ppc_brcond14abs", 16, 14, 0 },
|
||||
{ "fixup_ppc_half16", 0, 16, 0 },
|
||||
{ "fixup_ppc_half16ds", 0, 14, 0 },
|
||||
{ "fixup_ppc_nofixup", 0, 0, 0 }
|
||||
};
|
||||
const static MCFixupKindInfo InfosLE[PPC::NumTargetFixupKinds] = {
|
||||
// name offset bits flags
|
||||
{ "fixup_ppc_br24", 2, 24, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_ppc_brcond14", 2, 14, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_ppc_br24abs", 2, 24, 0 },
|
||||
{ "fixup_ppc_brcond14abs", 2, 14, 0 },
|
||||
{ "fixup_ppc_half16", 0, 16, 0 },
|
||||
{ "fixup_ppc_half16ds", 2, 14, 0 },
|
||||
{ "fixup_ppc_nofixup", 0, 0, 0 }
|
||||
};
|
||||
|
||||
if (Kind < FirstTargetFixupKind)
|
||||
return MCAsmBackend::getFixupKindInfo(Kind);
|
||||
|
||||
assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
|
||||
"Invalid kind!");
|
||||
return (IsLittleEndian? InfosLE : InfosBE)[Kind - FirstTargetFixupKind];
|
||||
}
|
||||
|
||||
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
|
||||
const MCValue &Target, MutableArrayRef<char> Data,
|
||||
uint64_t Value, bool IsResolved) const override {
|
||||
Value = adjustFixupValue(Fixup.getKind(), Value);
|
||||
if (!Value) return; // Doesn't change encoding.
|
||||
|
||||
unsigned Offset = Fixup.getOffset();
|
||||
unsigned NumBytes = getFixupKindNumBytes(Fixup.getKind());
|
||||
|
||||
// For each byte of the fragment that the fixup touches, mask in the bits
|
||||
// from the fixup value. The Value has been "split up" into the appropriate
|
||||
// bitfields above.
|
||||
for (unsigned i = 0; i != NumBytes; ++i) {
|
||||
unsigned Idx = IsLittleEndian ? i : (NumBytes - 1 - i);
|
||||
Data[Offset + i] |= uint8_t((Value >> (Idx * 8)) & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
|
||||
const MCValue &Target) override {
|
||||
switch ((PPC::Fixups)Fixup.getKind()) {
|
||||
default:
|
||||
return false;
|
||||
case PPC::fixup_ppc_br24:
|
||||
case PPC::fixup_ppc_br24abs:
|
||||
// If the target symbol has a local entry point we must not attempt
|
||||
// to resolve the fixup directly. Emit a relocation and leave
|
||||
// resolution of the final target address to the linker.
|
||||
if (const MCSymbolRefExpr *A = Target.getSymA()) {
|
||||
if (const auto *S = dyn_cast<MCSymbolELF>(&A->getSymbol())) {
|
||||
// The "other" values are stored in the last 6 bits of the second
|
||||
// byte. The traditional defines for STO values assume the full byte
|
||||
// and thus the shift to pack it.
|
||||
unsigned Other = S->getOther() << 2;
|
||||
if ((Other & ELF::STO_PPC64_LOCAL_MASK) != 0)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool mayNeedRelaxation(const MCInst &Inst) const override {
|
||||
// FIXME.
|
||||
return false;
|
||||
}
|
||||
|
||||
bool fixupNeedsRelaxation(const MCFixup &Fixup,
|
||||
uint64_t Value,
|
||||
const MCRelaxableFragment *DF,
|
||||
const MCAsmLayout &Layout) const override {
|
||||
// FIXME.
|
||||
llvm_unreachable("relaxInstruction() unimplemented");
|
||||
}
|
||||
|
||||
void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
|
||||
MCInst &Res) const override {
|
||||
// FIXME.
|
||||
llvm_unreachable("relaxInstruction() unimplemented");
|
||||
}
|
||||
|
||||
bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override {
|
||||
uint64_t NumNops = Count / 4;
|
||||
for (uint64_t i = 0; i != NumNops; ++i)
|
||||
OW->write32(0x60000000);
|
||||
|
||||
OW->WriteZeros(Count % 4);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
unsigned getPointerSize() const {
|
||||
StringRef Name = TheTarget.getName();
|
||||
if (Name == "ppc64" || Name == "ppc64le") return 8;
|
||||
assert(Name == "ppc32" && "Unknown target name!");
|
||||
return 4;
|
||||
}
|
||||
|
||||
bool isLittleEndian() const {
|
||||
return IsLittleEndian;
|
||||
}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
|
||||
// FIXME: This should be in a separate file.
|
||||
namespace {
|
||||
class DarwinPPCAsmBackend : public PPCAsmBackend {
|
||||
public:
|
||||
DarwinPPCAsmBackend(const Target &T) : PPCAsmBackend(T, false) { }
|
||||
|
||||
std::unique_ptr<MCObjectWriter>
|
||||
createObjectWriter(raw_pwrite_stream &OS) const override {
|
||||
bool is64 = getPointerSize() == 8;
|
||||
return createPPCMachObjectWriter(
|
||||
OS,
|
||||
/*Is64Bit=*/is64,
|
||||
(is64 ? MachO::CPU_TYPE_POWERPC64 : MachO::CPU_TYPE_POWERPC),
|
||||
MachO::CPU_SUBTYPE_POWERPC_ALL);
|
||||
}
|
||||
};
|
||||
|
||||
class ELFPPCAsmBackend : public PPCAsmBackend {
|
||||
uint8_t OSABI;
|
||||
public:
|
||||
ELFPPCAsmBackend(const Target &T, bool IsLittleEndian, uint8_t OSABI) :
|
||||
PPCAsmBackend(T, IsLittleEndian), OSABI(OSABI) { }
|
||||
|
||||
std::unique_ptr<MCObjectWriter>
|
||||
createObjectWriter(raw_pwrite_stream &OS) const override {
|
||||
bool is64 = getPointerSize() == 8;
|
||||
return createPPCELFObjectWriter(OS, is64, isLittleEndian(), OSABI);
|
||||
}
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
MCAsmBackend *llvm::createPPCAsmBackend(const Target &T,
|
||||
const MCSubtargetInfo &STI,
|
||||
const MCRegisterInfo &MRI,
|
||||
const MCTargetOptions &Options) {
|
||||
const Triple &TT = STI.getTargetTriple();
|
||||
if (TT.isOSDarwin())
|
||||
return new DarwinPPCAsmBackend(T);
|
||||
|
||||
uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(TT.getOS());
|
||||
bool IsLittleEndian = TT.getArch() == Triple::ppc64le;
|
||||
return new ELFPPCAsmBackend(T, IsLittleEndian, OSABI);
|
||||
}
|
@ -1,425 +0,0 @@
|
||||
//===-- PPCELFObjectWriter.cpp - PPC ELF Writer ---------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "MCTargetDesc/PPCFixupKinds.h"
|
||||
#include "MCTargetDesc/PPCMCExpr.h"
|
||||
#include "MCTargetDesc/PPCMCTargetDesc.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/MC/MCELFObjectWriter.h"
|
||||
#include "llvm/MC/MCExpr.h"
|
||||
#include "llvm/MC/MCObjectWriter.h"
|
||||
#include "llvm/MC/MCSymbolELF.h"
|
||||
#include "llvm/MC/MCValue.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
class PPCELFObjectWriter : public MCELFObjectTargetWriter {
|
||||
public:
|
||||
PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI);
|
||||
|
||||
protected:
|
||||
unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
|
||||
const MCFixup &Fixup, bool IsPCRel) const override;
|
||||
|
||||
bool needsRelocateWithSymbol(const MCSymbol &Sym,
|
||||
unsigned Type) const override;
|
||||
};
|
||||
}
|
||||
|
||||
PPCELFObjectWriter::PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI)
|
||||
: MCELFObjectTargetWriter(Is64Bit, OSABI,
|
||||
Is64Bit ? ELF::EM_PPC64 : ELF::EM_PPC,
|
||||
/*HasRelocationAddend*/ true) {}
|
||||
|
||||
static MCSymbolRefExpr::VariantKind getAccessVariant(const MCValue &Target,
|
||||
const MCFixup &Fixup) {
|
||||
const MCExpr *Expr = Fixup.getValue();
|
||||
|
||||
if (Expr->getKind() != MCExpr::Target)
|
||||
return Target.getAccessVariant();
|
||||
|
||||
switch (cast<PPCMCExpr>(Expr)->getKind()) {
|
||||
case PPCMCExpr::VK_PPC_None:
|
||||
return MCSymbolRefExpr::VK_None;
|
||||
case PPCMCExpr::VK_PPC_LO:
|
||||
return MCSymbolRefExpr::VK_PPC_LO;
|
||||
case PPCMCExpr::VK_PPC_HI:
|
||||
return MCSymbolRefExpr::VK_PPC_HI;
|
||||
case PPCMCExpr::VK_PPC_HA:
|
||||
return MCSymbolRefExpr::VK_PPC_HA;
|
||||
case PPCMCExpr::VK_PPC_HIGHERA:
|
||||
return MCSymbolRefExpr::VK_PPC_HIGHERA;
|
||||
case PPCMCExpr::VK_PPC_HIGHER:
|
||||
return MCSymbolRefExpr::VK_PPC_HIGHER;
|
||||
case PPCMCExpr::VK_PPC_HIGHEST:
|
||||
return MCSymbolRefExpr::VK_PPC_HIGHEST;
|
||||
case PPCMCExpr::VK_PPC_HIGHESTA:
|
||||
return MCSymbolRefExpr::VK_PPC_HIGHESTA;
|
||||
}
|
||||
llvm_unreachable("unknown PPCMCExpr kind");
|
||||
}
|
||||
|
||||
unsigned PPCELFObjectWriter::getRelocType(MCContext &Ctx, const MCValue &Target,
|
||||
const MCFixup &Fixup,
|
||||
bool IsPCRel) const {
|
||||
MCSymbolRefExpr::VariantKind Modifier = getAccessVariant(Target, Fixup);
|
||||
|
||||
// determine the type of the relocation
|
||||
unsigned Type;
|
||||
if (IsPCRel) {
|
||||
switch ((unsigned)Fixup.getKind()) {
|
||||
default:
|
||||
llvm_unreachable("Unimplemented");
|
||||
case PPC::fixup_ppc_br24:
|
||||
case PPC::fixup_ppc_br24abs:
|
||||
switch (Modifier) {
|
||||
default: llvm_unreachable("Unsupported Modifier");
|
||||
case MCSymbolRefExpr::VK_None:
|
||||
Type = ELF::R_PPC_REL24;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PLT:
|
||||
Type = ELF::R_PPC_PLTREL24;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_LOCAL:
|
||||
Type = ELF::R_PPC_LOCAL24PC;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PPC::fixup_ppc_brcond14:
|
||||
case PPC::fixup_ppc_brcond14abs:
|
||||
Type = ELF::R_PPC_REL14;
|
||||
break;
|
||||
case PPC::fixup_ppc_half16:
|
||||
switch (Modifier) {
|
||||
default: llvm_unreachable("Unsupported Modifier");
|
||||
case MCSymbolRefExpr::VK_None:
|
||||
Type = ELF::R_PPC_REL16;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_LO:
|
||||
Type = ELF::R_PPC_REL16_LO;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_HI:
|
||||
Type = ELF::R_PPC_REL16_HI;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_HA:
|
||||
Type = ELF::R_PPC_REL16_HA;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PPC::fixup_ppc_half16ds:
|
||||
Target.print(errs());
|
||||
errs() << '\n';
|
||||
report_fatal_error("Invalid PC-relative half16ds relocation");
|
||||
case FK_Data_4:
|
||||
case FK_PCRel_4:
|
||||
Type = ELF::R_PPC_REL32;
|
||||
break;
|
||||
case FK_Data_8:
|
||||
case FK_PCRel_8:
|
||||
Type = ELF::R_PPC64_REL64;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch ((unsigned)Fixup.getKind()) {
|
||||
default: llvm_unreachable("invalid fixup kind!");
|
||||
case PPC::fixup_ppc_br24abs:
|
||||
Type = ELF::R_PPC_ADDR24;
|
||||
break;
|
||||
case PPC::fixup_ppc_brcond14abs:
|
||||
Type = ELF::R_PPC_ADDR14; // XXX: or BRNTAKEN?_
|
||||
break;
|
||||
case PPC::fixup_ppc_half16:
|
||||
switch (Modifier) {
|
||||
default: llvm_unreachable("Unsupported Modifier");
|
||||
case MCSymbolRefExpr::VK_None:
|
||||
Type = ELF::R_PPC_ADDR16;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_LO:
|
||||
Type = ELF::R_PPC_ADDR16_LO;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_HI:
|
||||
Type = ELF::R_PPC_ADDR16_HI;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_HA:
|
||||
Type = ELF::R_PPC_ADDR16_HA;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_HIGHER:
|
||||
Type = ELF::R_PPC64_ADDR16_HIGHER;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_HIGHERA:
|
||||
Type = ELF::R_PPC64_ADDR16_HIGHERA;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_HIGHEST:
|
||||
Type = ELF::R_PPC64_ADDR16_HIGHEST;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_HIGHESTA:
|
||||
Type = ELF::R_PPC64_ADDR16_HIGHESTA;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_GOT:
|
||||
Type = ELF::R_PPC_GOT16;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_GOT_LO:
|
||||
Type = ELF::R_PPC_GOT16_LO;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_GOT_HI:
|
||||
Type = ELF::R_PPC_GOT16_HI;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_GOT_HA:
|
||||
Type = ELF::R_PPC_GOT16_HA;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_TOC:
|
||||
Type = ELF::R_PPC64_TOC16;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_TOC_LO:
|
||||
Type = ELF::R_PPC64_TOC16_LO;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_TOC_HI:
|
||||
Type = ELF::R_PPC64_TOC16_HI;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_TOC_HA:
|
||||
Type = ELF::R_PPC64_TOC16_HA;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_TPREL:
|
||||
Type = ELF::R_PPC_TPREL16;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_TPREL_LO:
|
||||
Type = ELF::R_PPC_TPREL16_LO;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_TPREL_HI:
|
||||
Type = ELF::R_PPC_TPREL16_HI;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_TPREL_HA:
|
||||
Type = ELF::R_PPC_TPREL16_HA;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER:
|
||||
Type = ELF::R_PPC64_TPREL16_HIGHER;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA:
|
||||
Type = ELF::R_PPC64_TPREL16_HIGHERA;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST:
|
||||
Type = ELF::R_PPC64_TPREL16_HIGHEST;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA:
|
||||
Type = ELF::R_PPC64_TPREL16_HIGHESTA;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_DTPREL:
|
||||
Type = ELF::R_PPC64_DTPREL16;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
|
||||
Type = ELF::R_PPC64_DTPREL16_LO;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_DTPREL_HI:
|
||||
Type = ELF::R_PPC64_DTPREL16_HI;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_DTPREL_HA:
|
||||
Type = ELF::R_PPC64_DTPREL16_HA;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER:
|
||||
Type = ELF::R_PPC64_DTPREL16_HIGHER;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA:
|
||||
Type = ELF::R_PPC64_DTPREL16_HIGHERA;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST:
|
||||
Type = ELF::R_PPC64_DTPREL16_HIGHEST;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHESTA:
|
||||
Type = ELF::R_PPC64_DTPREL16_HIGHESTA;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_GOT_TLSGD:
|
||||
if (is64Bit())
|
||||
Type = ELF::R_PPC64_GOT_TLSGD16;
|
||||
else
|
||||
Type = ELF::R_PPC_GOT_TLSGD16;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO:
|
||||
Type = ELF::R_PPC64_GOT_TLSGD16_LO;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI:
|
||||
Type = ELF::R_PPC64_GOT_TLSGD16_HI;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA:
|
||||
Type = ELF::R_PPC64_GOT_TLSGD16_HA;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_GOT_TLSLD:
|
||||
if (is64Bit())
|
||||
Type = ELF::R_PPC64_GOT_TLSLD16;
|
||||
else
|
||||
Type = ELF::R_PPC_GOT_TLSLD16;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO:
|
||||
Type = ELF::R_PPC64_GOT_TLSLD16_LO;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI:
|
||||
Type = ELF::R_PPC64_GOT_TLSLD16_HI;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA:
|
||||
Type = ELF::R_PPC64_GOT_TLSLD16_HA;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_GOT_TPREL:
|
||||
/* We don't have R_PPC64_GOT_TPREL16, but since GOT offsets
|
||||
are always 4-aligned, we can use R_PPC64_GOT_TPREL16_DS. */
|
||||
Type = ELF::R_PPC64_GOT_TPREL16_DS;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
|
||||
/* We don't have R_PPC64_GOT_TPREL16_LO, but since GOT offsets
|
||||
are always 4-aligned, we can use R_PPC64_GOT_TPREL16_LO_DS. */
|
||||
Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI:
|
||||
Type = ELF::R_PPC64_GOT_TPREL16_HI;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
|
||||
/* We don't have R_PPC64_GOT_DTPREL16, but since GOT offsets
|
||||
are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_DS. */
|
||||
Type = ELF::R_PPC64_GOT_DTPREL16_DS;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
|
||||
/* We don't have R_PPC64_GOT_DTPREL16_LO, but since GOT offsets
|
||||
are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_LO_DS. */
|
||||
Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA:
|
||||
Type = ELF::R_PPC64_GOT_TPREL16_HA;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI:
|
||||
Type = ELF::R_PPC64_GOT_DTPREL16_HI;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA:
|
||||
Type = ELF::R_PPC64_GOT_DTPREL16_HA;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PPC::fixup_ppc_half16ds:
|
||||
switch (Modifier) {
|
||||
default: llvm_unreachable("Unsupported Modifier");
|
||||
case MCSymbolRefExpr::VK_None:
|
||||
Type = ELF::R_PPC64_ADDR16_DS;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_LO:
|
||||
Type = ELF::R_PPC64_ADDR16_LO_DS;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_GOT:
|
||||
Type = ELF::R_PPC64_GOT16_DS;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_GOT_LO:
|
||||
Type = ELF::R_PPC64_GOT16_LO_DS;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_TOC:
|
||||
Type = ELF::R_PPC64_TOC16_DS;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_TOC_LO:
|
||||
Type = ELF::R_PPC64_TOC16_LO_DS;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_TPREL:
|
||||
Type = ELF::R_PPC64_TPREL16_DS;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_TPREL_LO:
|
||||
Type = ELF::R_PPC64_TPREL16_LO_DS;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_DTPREL:
|
||||
Type = ELF::R_PPC64_DTPREL16_DS;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_DTPREL_LO:
|
||||
Type = ELF::R_PPC64_DTPREL16_LO_DS;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_GOT_TPREL:
|
||||
Type = ELF::R_PPC64_GOT_TPREL16_DS;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO:
|
||||
Type = ELF::R_PPC64_GOT_TPREL16_LO_DS;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_GOT_DTPREL:
|
||||
Type = ELF::R_PPC64_GOT_DTPREL16_DS;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO:
|
||||
Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case PPC::fixup_ppc_nofixup:
|
||||
switch (Modifier) {
|
||||
default: llvm_unreachable("Unsupported Modifier");
|
||||
case MCSymbolRefExpr::VK_PPC_TLSGD:
|
||||
if (is64Bit())
|
||||
Type = ELF::R_PPC64_TLSGD;
|
||||
else
|
||||
Type = ELF::R_PPC_TLSGD;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_TLSLD:
|
||||
if (is64Bit())
|
||||
Type = ELF::R_PPC64_TLSLD;
|
||||
else
|
||||
Type = ELF::R_PPC_TLSLD;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_TLS:
|
||||
if (is64Bit())
|
||||
Type = ELF::R_PPC64_TLS;
|
||||
else
|
||||
Type = ELF::R_PPC_TLS;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case FK_Data_8:
|
||||
switch (Modifier) {
|
||||
default: llvm_unreachable("Unsupported Modifier");
|
||||
case MCSymbolRefExpr::VK_PPC_TOCBASE:
|
||||
Type = ELF::R_PPC64_TOC;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_None:
|
||||
Type = ELF::R_PPC64_ADDR64;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_PPC_DTPMOD:
|
||||
Type = ELF::R_PPC64_DTPMOD64;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_TPREL:
|
||||
Type = ELF::R_PPC64_TPREL64;
|
||||
break;
|
||||
case MCSymbolRefExpr::VK_DTPREL:
|
||||
Type = ELF::R_PPC64_DTPREL64;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case FK_Data_4:
|
||||
Type = ELF::R_PPC_ADDR32;
|
||||
break;
|
||||
case FK_Data_2:
|
||||
Type = ELF::R_PPC_ADDR16;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return Type;
|
||||
}
|
||||
|
||||
bool PPCELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym,
|
||||
unsigned Type) const {
|
||||
switch (Type) {
|
||||
default:
|
||||
return false;
|
||||
|
||||
case ELF::R_PPC_REL24:
|
||||
// If the target symbol has a local entry point, we must keep the
|
||||
// target symbol to preserve that information for the linker.
|
||||
// The "other" values are stored in the last 6 bits of the second byte.
|
||||
// The traditional defines for STO values assume the full byte and thus
|
||||
// the shift to pack it.
|
||||
unsigned Other = cast<MCSymbolELF>(Sym).getOther() << 2;
|
||||
return (Other & ELF::STO_PPC64_LOCAL_MASK) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<MCObjectWriter>
|
||||
llvm::createPPCELFObjectWriter(raw_pwrite_stream &OS, bool Is64Bit,
|
||||
bool IsLittleEndian, uint8_t OSABI) {
|
||||
auto MOTW = llvm::make_unique<PPCELFObjectWriter>(Is64Bit, OSABI);
|
||||
return createELFObjectWriter(std::move(MOTW), OS, IsLittleEndian);
|
||||
}
|
@ -1,52 +0,0 @@
|
||||
//===-- PPCFixupKinds.h - PPC Specific Fixup Entries ------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIB_TARGET_POWERPC_MCTARGETDESC_PPCFIXUPKINDS_H
|
||||
#define LLVM_LIB_TARGET_POWERPC_MCTARGETDESC_PPCFIXUPKINDS_H
|
||||
|
||||
#include "llvm/MC/MCFixup.h"
|
||||
|
||||
#undef PPC
|
||||
|
||||
namespace llvm {
|
||||
namespace PPC {
|
||||
enum Fixups {
|
||||
// 24-bit PC relative relocation for direct branches like 'b' and 'bl'.
|
||||
fixup_ppc_br24 = FirstTargetFixupKind,
|
||||
|
||||
/// 14-bit PC relative relocation for conditional branches.
|
||||
fixup_ppc_brcond14,
|
||||
|
||||
/// 24-bit absolute relocation for direct branches like 'ba' and 'bla'.
|
||||
fixup_ppc_br24abs,
|
||||
|
||||
/// 14-bit absolute relocation for conditional branches.
|
||||
fixup_ppc_brcond14abs,
|
||||
|
||||
/// A 16-bit fixup corresponding to lo16(_foo) or ha16(_foo) for instrs like
|
||||
/// 'li' or 'addis'.
|
||||
fixup_ppc_half16,
|
||||
|
||||
/// A 14-bit fixup corresponding to lo16(_foo) with implied 2 zero bits for
|
||||
/// instrs like 'std'.
|
||||
fixup_ppc_half16ds,
|
||||
|
||||
/// Not a true fixup, but ties a symbol to a call to __tls_get_addr for the
|
||||
/// TLS general and local dynamic models, or inserts the thread-pointer
|
||||
/// register number.
|
||||
fixup_ppc_nofixup,
|
||||
|
||||
// Marker
|
||||
LastTargetFixupKind,
|
||||
NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,84 +0,0 @@
|
||||
//===-- PPCMCAsmInfo.cpp - PPC asm properties -----------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains the declarations of the MCAsmInfoDarwin properties.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "PPCMCAsmInfo.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
void PPCMCAsmInfoDarwin::anchor() { }
|
||||
|
||||
PPCMCAsmInfoDarwin::PPCMCAsmInfoDarwin(bool is64Bit, const Triple& T) {
|
||||
if (is64Bit) {
|
||||
CodePointerSize = CalleeSaveStackSlotSize = 8;
|
||||
}
|
||||
IsLittleEndian = false;
|
||||
|
||||
SeparatorString = "@";
|
||||
CommentString = ";";
|
||||
ExceptionsType = ExceptionHandling::DwarfCFI;
|
||||
|
||||
if (!is64Bit)
|
||||
Data64bitsDirective = nullptr; // We can't emit a 64-bit unit in PPC32 mode.
|
||||
|
||||
AssemblerDialect = 1; // New-Style mnemonics.
|
||||
SupportsDebugInformation= true; // Debug information.
|
||||
|
||||
// The installed assembler for OSX < 10.6 lacks some directives.
|
||||
// FIXME: this should really be a check on the assembler characteristics
|
||||
// rather than OS version
|
||||
if (T.isMacOSX() && T.isMacOSXVersionLT(10, 6))
|
||||
HasWeakDefCanBeHiddenDirective = false;
|
||||
|
||||
UseIntegratedAssembler = true;
|
||||
}
|
||||
|
||||
void PPCELFMCAsmInfo::anchor() { }
|
||||
|
||||
PPCELFMCAsmInfo::PPCELFMCAsmInfo(bool is64Bit, const Triple& T) {
|
||||
// FIXME: This is not always needed. For example, it is not needed in the
|
||||
// v2 abi.
|
||||
NeedsLocalForSize = true;
|
||||
|
||||
if (is64Bit) {
|
||||
CodePointerSize = CalleeSaveStackSlotSize = 8;
|
||||
}
|
||||
IsLittleEndian = T.getArch() == Triple::ppc64le;
|
||||
|
||||
// ".comm align is in bytes but .align is pow-2."
|
||||
AlignmentIsInBytes = false;
|
||||
|
||||
CommentString = "#";
|
||||
|
||||
// Uses '.section' before '.bss' directive
|
||||
UsesELFSectionDirectiveForBSS = true;
|
||||
|
||||
// Debug Information
|
||||
SupportsDebugInformation = true;
|
||||
|
||||
DollarIsPC = true;
|
||||
|
||||
// Set up DWARF directives
|
||||
MinInstAlignment = 4;
|
||||
|
||||
// Exceptions handling
|
||||
ExceptionsType = ExceptionHandling::DwarfCFI;
|
||||
|
||||
ZeroDirective = "\t.space\t";
|
||||
Data64bitsDirective = is64Bit ? "\t.quad\t" : nullptr;
|
||||
AssemblerDialect = 1; // New-Style mnemonics.
|
||||
LCOMMDirectiveAlignmentType = LCOMM::ByteAlignment;
|
||||
|
||||
UseIntegratedAssembler = true;
|
||||
}
|
||||
|
@ -1,39 +0,0 @@
|
||||
//===-- PPCMCAsmInfo.h - PPC asm properties --------------------*- C++ -*--===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file contains the declaration of the MCAsmInfoDarwin class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIB_TARGET_POWERPC_MCTARGETDESC_PPCMCASMINFO_H
|
||||
#define LLVM_LIB_TARGET_POWERPC_MCTARGETDESC_PPCMCASMINFO_H
|
||||
|
||||
#include "llvm/MC/MCAsmInfoDarwin.h"
|
||||
#include "llvm/MC/MCAsmInfoELF.h"
|
||||
|
||||
namespace llvm {
|
||||
class Triple;
|
||||
|
||||
class PPCMCAsmInfoDarwin : public MCAsmInfoDarwin {
|
||||
virtual void anchor();
|
||||
|
||||
public:
|
||||
explicit PPCMCAsmInfoDarwin(bool is64Bit, const Triple &);
|
||||
};
|
||||
|
||||
class PPCELFMCAsmInfo : public MCAsmInfoELF {
|
||||
void anchor() override;
|
||||
|
||||
public:
|
||||
explicit PPCELFMCAsmInfo(bool is64Bit, const Triple &);
|
||||
};
|
||||
|
||||
} // namespace llvm
|
||||
|
||||
#endif
|
@ -1,390 +0,0 @@
|
||||
//===-- PPCMCCodeEmitter.cpp - Convert PPC code to machine code -----------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements the PPCMCCodeEmitter class.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "MCTargetDesc/PPCFixupKinds.h"
|
||||
#include "PPCInstrInfo.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
#include "llvm/MC/MCAsmInfo.h"
|
||||
#include "llvm/MC/MCCodeEmitter.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCFixup.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/MC/MCInstrDesc.h"
|
||||
#include "llvm/MC/MCInstrInfo.h"
|
||||
#include "llvm/MC/MCRegisterInfo.h"
|
||||
#include "llvm/MC/MCSubtargetInfo.h"
|
||||
#include "llvm/Support/Endian.h"
|
||||
#include "llvm/Support/EndianStream.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "mccodeemitter"
|
||||
|
||||
STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
|
||||
|
||||
namespace {
|
||||
|
||||
class PPCMCCodeEmitter : public MCCodeEmitter {
|
||||
const MCInstrInfo &MCII;
|
||||
const MCContext &CTX;
|
||||
bool IsLittleEndian;
|
||||
|
||||
public:
|
||||
PPCMCCodeEmitter(const MCInstrInfo &mcii, MCContext &ctx)
|
||||
: MCII(mcii), CTX(ctx),
|
||||
IsLittleEndian(ctx.getAsmInfo()->isLittleEndian()) {}
|
||||
PPCMCCodeEmitter(const PPCMCCodeEmitter &) = delete;
|
||||
void operator=(const PPCMCCodeEmitter &) = delete;
|
||||
~PPCMCCodeEmitter() override = default;
|
||||
|
||||
unsigned getDirectBrEncoding(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const;
|
||||
unsigned getCondBrEncoding(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const;
|
||||
unsigned getAbsDirectBrEncoding(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const;
|
||||
unsigned getAbsCondBrEncoding(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const;
|
||||
unsigned getImm16Encoding(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const;
|
||||
unsigned getMemRIEncoding(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const;
|
||||
unsigned getMemRIXEncoding(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const;
|
||||
unsigned getMemRIX16Encoding(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const;
|
||||
unsigned getSPE8DisEncoding(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const;
|
||||
unsigned getSPE4DisEncoding(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const;
|
||||
unsigned getSPE2DisEncoding(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const;
|
||||
unsigned getTLSRegEncoding(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const;
|
||||
unsigned getTLSCallEncoding(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const;
|
||||
unsigned get_crbitm_encoding(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const;
|
||||
|
||||
/// getMachineOpValue - Return binary encoding of operand. If the machine
|
||||
/// operand requires relocation, record the relocation and return zero.
|
||||
unsigned getMachineOpValue(const MCInst &MI,const MCOperand &MO,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const;
|
||||
|
||||
// getBinaryCodeForInstr - TableGen'erated function for getting the
|
||||
// binary encoding for an instruction.
|
||||
uint64_t getBinaryCodeForInstr(const MCInst &MI,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const;
|
||||
|
||||
void encodeInstruction(const MCInst &MI, raw_ostream &OS,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const override {
|
||||
verifyInstructionPredicates(MI,
|
||||
computeAvailableFeatures(STI.getFeatureBits()));
|
||||
|
||||
unsigned Opcode = MI.getOpcode();
|
||||
const MCInstrDesc &Desc = MCII.get(Opcode);
|
||||
|
||||
uint64_t Bits = getBinaryCodeForInstr(MI, Fixups, STI);
|
||||
|
||||
// Output the constant in big/little endian byte order.
|
||||
unsigned Size = Desc.getSize();
|
||||
switch (Size) {
|
||||
case 0:
|
||||
break;
|
||||
case 4:
|
||||
if (IsLittleEndian) {
|
||||
support::endian::Writer<support::little>(OS).write<uint32_t>(Bits);
|
||||
} else {
|
||||
support::endian::Writer<support::big>(OS).write<uint32_t>(Bits);
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
// If we emit a pair of instructions, the first one is
|
||||
// always in the top 32 bits, even on little-endian.
|
||||
if (IsLittleEndian) {
|
||||
uint64_t Swapped = (Bits << 32) | (Bits >> 32);
|
||||
support::endian::Writer<support::little>(OS).write<uint64_t>(Swapped);
|
||||
} else {
|
||||
support::endian::Writer<support::big>(OS).write<uint64_t>(Bits);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("Invalid instruction size");
|
||||
}
|
||||
|
||||
++MCNumEmitted; // Keep track of the # of mi's emitted.
|
||||
}
|
||||
|
||||
private:
|
||||
uint64_t computeAvailableFeatures(const FeatureBitset &FB) const;
|
||||
void verifyInstructionPredicates(const MCInst &MI,
|
||||
uint64_t AvailableFeatures) const;
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
MCCodeEmitter *llvm::createPPCMCCodeEmitter(const MCInstrInfo &MCII,
|
||||
const MCRegisterInfo &MRI,
|
||||
MCContext &Ctx) {
|
||||
return new PPCMCCodeEmitter(MCII, Ctx);
|
||||
}
|
||||
|
||||
unsigned PPCMCCodeEmitter::
|
||||
getDirectBrEncoding(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const {
|
||||
const MCOperand &MO = MI.getOperand(OpNo);
|
||||
if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI);
|
||||
|
||||
// Add a fixup for the branch target.
|
||||
Fixups.push_back(MCFixup::create(0, MO.getExpr(),
|
||||
(MCFixupKind)PPC::fixup_ppc_br24));
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned PPCMCCodeEmitter::getCondBrEncoding(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const {
|
||||
const MCOperand &MO = MI.getOperand(OpNo);
|
||||
if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI);
|
||||
|
||||
// Add a fixup for the branch target.
|
||||
Fixups.push_back(MCFixup::create(0, MO.getExpr(),
|
||||
(MCFixupKind)PPC::fixup_ppc_brcond14));
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned PPCMCCodeEmitter::
|
||||
getAbsDirectBrEncoding(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const {
|
||||
const MCOperand &MO = MI.getOperand(OpNo);
|
||||
if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI);
|
||||
|
||||
// Add a fixup for the branch target.
|
||||
Fixups.push_back(MCFixup::create(0, MO.getExpr(),
|
||||
(MCFixupKind)PPC::fixup_ppc_br24abs));
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned PPCMCCodeEmitter::
|
||||
getAbsCondBrEncoding(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const {
|
||||
const MCOperand &MO = MI.getOperand(OpNo);
|
||||
if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI);
|
||||
|
||||
// Add a fixup for the branch target.
|
||||
Fixups.push_back(MCFixup::create(0, MO.getExpr(),
|
||||
(MCFixupKind)PPC::fixup_ppc_brcond14abs));
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned PPCMCCodeEmitter::getImm16Encoding(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const {
|
||||
const MCOperand &MO = MI.getOperand(OpNo);
|
||||
if (MO.isReg() || MO.isImm()) return getMachineOpValue(MI, MO, Fixups, STI);
|
||||
|
||||
// Add a fixup for the immediate field.
|
||||
Fixups.push_back(MCFixup::create(IsLittleEndian? 0 : 2, MO.getExpr(),
|
||||
(MCFixupKind)PPC::fixup_ppc_half16));
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned PPCMCCodeEmitter::getMemRIEncoding(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const {
|
||||
// Encode (imm, reg) as a memri, which has the low 16-bits as the
|
||||
// displacement and the next 5 bits as the register #.
|
||||
assert(MI.getOperand(OpNo+1).isReg());
|
||||
unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI) << 16;
|
||||
|
||||
const MCOperand &MO = MI.getOperand(OpNo);
|
||||
if (MO.isImm())
|
||||
return (getMachineOpValue(MI, MO, Fixups, STI) & 0xFFFF) | RegBits;
|
||||
|
||||
// Add a fixup for the displacement field.
|
||||
Fixups.push_back(MCFixup::create(IsLittleEndian? 0 : 2, MO.getExpr(),
|
||||
(MCFixupKind)PPC::fixup_ppc_half16));
|
||||
return RegBits;
|
||||
}
|
||||
|
||||
unsigned PPCMCCodeEmitter::getMemRIXEncoding(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const {
|
||||
// Encode (imm, reg) as a memrix, which has the low 14-bits as the
|
||||
// displacement and the next 5 bits as the register #.
|
||||
assert(MI.getOperand(OpNo+1).isReg());
|
||||
unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI) << 14;
|
||||
|
||||
const MCOperand &MO = MI.getOperand(OpNo);
|
||||
if (MO.isImm())
|
||||
return ((getMachineOpValue(MI, MO, Fixups, STI) >> 2) & 0x3FFF) | RegBits;
|
||||
|
||||
// Add a fixup for the displacement field.
|
||||
Fixups.push_back(MCFixup::create(IsLittleEndian? 0 : 2, MO.getExpr(),
|
||||
(MCFixupKind)PPC::fixup_ppc_half16ds));
|
||||
return RegBits;
|
||||
}
|
||||
|
||||
unsigned PPCMCCodeEmitter::getMemRIX16Encoding(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const {
|
||||
// Encode (imm, reg) as a memrix16, which has the low 12-bits as the
|
||||
// displacement and the next 5 bits as the register #.
|
||||
assert(MI.getOperand(OpNo+1).isReg());
|
||||
unsigned RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI) << 12;
|
||||
|
||||
const MCOperand &MO = MI.getOperand(OpNo);
|
||||
assert(MO.isImm() && !(MO.getImm() % 16) &&
|
||||
"Expecting an immediate that is a multiple of 16");
|
||||
|
||||
return ((getMachineOpValue(MI, MO, Fixups, STI) >> 4) & 0xFFF) | RegBits;
|
||||
}
|
||||
|
||||
unsigned PPCMCCodeEmitter::getSPE8DisEncoding(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI)
|
||||
const {
|
||||
// Encode (imm, reg) as a spe8dis, which has the low 5-bits of (imm / 8)
|
||||
// as the displacement and the next 5 bits as the register #.
|
||||
assert(MI.getOperand(OpNo+1).isReg());
|
||||
uint32_t RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI) << 5;
|
||||
|
||||
const MCOperand &MO = MI.getOperand(OpNo);
|
||||
assert(MO.isImm());
|
||||
uint32_t Imm = getMachineOpValue(MI, MO, Fixups, STI) >> 3;
|
||||
return reverseBits(Imm | RegBits) >> 22;
|
||||
}
|
||||
|
||||
unsigned PPCMCCodeEmitter::getSPE4DisEncoding(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI)
|
||||
const {
|
||||
// Encode (imm, reg) as a spe4dis, which has the low 5-bits of (imm / 4)
|
||||
// as the displacement and the next 5 bits as the register #.
|
||||
assert(MI.getOperand(OpNo+1).isReg());
|
||||
uint32_t RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI) << 5;
|
||||
|
||||
const MCOperand &MO = MI.getOperand(OpNo);
|
||||
assert(MO.isImm());
|
||||
uint32_t Imm = getMachineOpValue(MI, MO, Fixups, STI) >> 2;
|
||||
return reverseBits(Imm | RegBits) >> 22;
|
||||
}
|
||||
|
||||
unsigned PPCMCCodeEmitter::getSPE2DisEncoding(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI)
|
||||
const {
|
||||
// Encode (imm, reg) as a spe2dis, which has the low 5-bits of (imm / 2)
|
||||
// as the displacement and the next 5 bits as the register #.
|
||||
assert(MI.getOperand(OpNo+1).isReg());
|
||||
uint32_t RegBits = getMachineOpValue(MI, MI.getOperand(OpNo+1), Fixups, STI) << 5;
|
||||
|
||||
const MCOperand &MO = MI.getOperand(OpNo);
|
||||
assert(MO.isImm());
|
||||
uint32_t Imm = getMachineOpValue(MI, MO, Fixups, STI) >> 1;
|
||||
return reverseBits(Imm | RegBits) >> 22;
|
||||
}
|
||||
|
||||
unsigned PPCMCCodeEmitter::getTLSRegEncoding(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const {
|
||||
const MCOperand &MO = MI.getOperand(OpNo);
|
||||
if (MO.isReg()) return getMachineOpValue(MI, MO, Fixups, STI);
|
||||
|
||||
// Add a fixup for the TLS register, which simply provides a relocation
|
||||
// hint to the linker that this statement is part of a relocation sequence.
|
||||
// Return the thread-pointer register's encoding.
|
||||
Fixups.push_back(MCFixup::create(0, MO.getExpr(),
|
||||
(MCFixupKind)PPC::fixup_ppc_nofixup));
|
||||
const Triple &TT = STI.getTargetTriple();
|
||||
bool isPPC64 = TT.getArch() == Triple::ppc64 || TT.getArch() == Triple::ppc64le;
|
||||
return CTX.getRegisterInfo()->getEncodingValue(isPPC64 ? PPC::X13 : PPC::R2);
|
||||
}
|
||||
|
||||
unsigned PPCMCCodeEmitter::getTLSCallEncoding(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const {
|
||||
// For special TLS calls, we need two fixups; one for the branch target
|
||||
// (__tls_get_addr), which we create via getDirectBrEncoding as usual,
|
||||
// and one for the TLSGD or TLSLD symbol, which is emitted here.
|
||||
const MCOperand &MO = MI.getOperand(OpNo+1);
|
||||
Fixups.push_back(MCFixup::create(0, MO.getExpr(),
|
||||
(MCFixupKind)PPC::fixup_ppc_nofixup));
|
||||
return getDirectBrEncoding(MI, OpNo, Fixups, STI);
|
||||
}
|
||||
|
||||
unsigned PPCMCCodeEmitter::
|
||||
get_crbitm_encoding(const MCInst &MI, unsigned OpNo,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const {
|
||||
const MCOperand &MO = MI.getOperand(OpNo);
|
||||
assert((MI.getOpcode() == PPC::MTOCRF || MI.getOpcode() == PPC::MTOCRF8 ||
|
||||
MI.getOpcode() == PPC::MFOCRF || MI.getOpcode() == PPC::MFOCRF8) &&
|
||||
(MO.getReg() >= PPC::CR0 && MO.getReg() <= PPC::CR7));
|
||||
return 0x80 >> CTX.getRegisterInfo()->getEncodingValue(MO.getReg());
|
||||
}
|
||||
|
||||
unsigned PPCMCCodeEmitter::
|
||||
getMachineOpValue(const MCInst &MI, const MCOperand &MO,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const {
|
||||
if (MO.isReg()) {
|
||||
// MTOCRF/MFOCRF should go through get_crbitm_encoding for the CR operand.
|
||||
// The GPR operand should come through here though.
|
||||
assert((MI.getOpcode() != PPC::MTOCRF && MI.getOpcode() != PPC::MTOCRF8 &&
|
||||
MI.getOpcode() != PPC::MFOCRF && MI.getOpcode() != PPC::MFOCRF8) ||
|
||||
MO.getReg() < PPC::CR0 || MO.getReg() > PPC::CR7);
|
||||
unsigned Reg = MO.getReg();
|
||||
unsigned Encode = CTX.getRegisterInfo()->getEncodingValue(Reg);
|
||||
|
||||
if ((MCII.get(MI.getOpcode()).TSFlags & PPCII::UseVSXReg))
|
||||
if (PPCInstrInfo::isVRRegister(Reg))
|
||||
Encode += 32;
|
||||
|
||||
return Encode;
|
||||
}
|
||||
|
||||
assert(MO.isImm() &&
|
||||
"Relocation required in an instruction that we cannot encode!");
|
||||
return MO.getImm();
|
||||
}
|
||||
|
||||
#define ENABLE_INSTR_PREDICATE_VERIFIER
|
||||
#include "PPCGenMCCodeEmitter.inc"
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user