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(LLVMSparcAsmParser
|
||||
SparcAsmParser.cpp
|
||||
)
|
@ -1,23 +0,0 @@
|
||||
;===- ./lib/Target/Sparc/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 = SparcAsmParser
|
||||
parent = Sparc
|
||||
required_libraries = MC MCParser SparcDesc SparcInfo Support
|
||||
add_to_library_groups = Sparc
|
File diff suppressed because it is too large
Load Diff
34
external/llvm/lib/Target/Sparc/CMakeLists.txt
vendored
34
external/llvm/lib/Target/Sparc/CMakeLists.txt
vendored
@ -1,34 +0,0 @@
|
||||
set(LLVM_TARGET_DEFINITIONS Sparc.td)
|
||||
|
||||
tablegen(LLVM SparcGenRegisterInfo.inc -gen-register-info)
|
||||
tablegen(LLVM SparcGenInstrInfo.inc -gen-instr-info)
|
||||
tablegen(LLVM SparcGenDisassemblerTables.inc -gen-disassembler)
|
||||
tablegen(LLVM SparcGenMCCodeEmitter.inc -gen-emitter)
|
||||
tablegen(LLVM SparcGenAsmWriter.inc -gen-asm-writer)
|
||||
tablegen(LLVM SparcGenAsmMatcher.inc -gen-asm-matcher)
|
||||
tablegen(LLVM SparcGenDAGISel.inc -gen-dag-isel)
|
||||
tablegen(LLVM SparcGenSubtargetInfo.inc -gen-subtarget)
|
||||
tablegen(LLVM SparcGenCallingConv.inc -gen-callingconv)
|
||||
add_public_tablegen_target(SparcCommonTableGen)
|
||||
|
||||
add_llvm_target(SparcCodeGen
|
||||
DelaySlotFiller.cpp
|
||||
LeonPasses.cpp
|
||||
SparcAsmPrinter.cpp
|
||||
SparcInstrInfo.cpp
|
||||
SparcISelDAGToDAG.cpp
|
||||
SparcISelLowering.cpp
|
||||
SparcFrameLowering.cpp
|
||||
SparcMachineFunctionInfo.cpp
|
||||
SparcRegisterInfo.cpp
|
||||
SparcSubtarget.cpp
|
||||
SparcTargetMachine.cpp
|
||||
SparcMCInstLower.cpp
|
||||
SparcTargetObjectFile.cpp
|
||||
)
|
||||
|
||||
add_subdirectory(TargetInfo)
|
||||
add_subdirectory(MCTargetDesc)
|
||||
add_subdirectory(InstPrinter)
|
||||
add_subdirectory(AsmParser)
|
||||
add_subdirectory(Disassembler)
|
512
external/llvm/lib/Target/Sparc/DelaySlotFiller.cpp
vendored
512
external/llvm/lib/Target/Sparc/DelaySlotFiller.cpp
vendored
File diff suppressed because it is too large
Load Diff
@ -1,3 +0,0 @@
|
||||
add_llvm_library(LLVMSparcDisassembler
|
||||
SparcDisassembler.cpp
|
||||
)
|
@ -1,23 +0,0 @@
|
||||
;===- ./lib/Target/Sparc/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 = SparcDisassembler
|
||||
parent = Sparc
|
||||
required_libraries = MCDisassembler SparcInfo Support
|
||||
add_to_library_groups = Sparc
|
File diff suppressed because it is too large
Load Diff
@ -1,3 +0,0 @@
|
||||
add_llvm_library(LLVMSparcAsmPrinter
|
||||
SparcInstPrinter.cpp
|
||||
)
|
@ -1,23 +0,0 @@
|
||||
;===- ./lib/Target/Sparc/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 = SparcAsmPrinter
|
||||
parent = Sparc
|
||||
required_libraries = MC Support
|
||||
add_to_library_groups = Sparc
|
@ -1,197 +0,0 @@
|
||||
//===-- SparcInstPrinter.cpp - Convert Sparc MCInst to assembly syntax -----==//
|
||||
//
|
||||
// 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 Sparc MCInst to a .s file.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "SparcInstPrinter.h"
|
||||
#include "Sparc.h"
|
||||
#include "llvm/MC/MCExpr.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/MC/MCRegisterInfo.h"
|
||||
#include "llvm/MC/MCSubtargetInfo.h"
|
||||
#include "llvm/MC/MCSymbol.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "asm-printer"
|
||||
|
||||
// The generated AsmMatcher SparcGenAsmWriter uses "Sparc" as the target
|
||||
// namespace. But SPARC backend uses "SP" as its namespace.
|
||||
namespace llvm {
|
||||
namespace Sparc {
|
||||
using namespace SP;
|
||||
}
|
||||
}
|
||||
|
||||
#define GET_INSTRUCTION_NAME
|
||||
#define PRINT_ALIAS_INSTR
|
||||
#include "SparcGenAsmWriter.inc"
|
||||
|
||||
bool SparcInstPrinter::isV9(const MCSubtargetInfo &STI) const {
|
||||
return (STI.getFeatureBits()[Sparc::FeatureV9]) != 0;
|
||||
}
|
||||
|
||||
void SparcInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const
|
||||
{
|
||||
OS << '%' << StringRef(getRegisterName(RegNo)).lower();
|
||||
}
|
||||
|
||||
void SparcInstPrinter::printInst(const MCInst *MI, raw_ostream &O,
|
||||
StringRef Annot, const MCSubtargetInfo &STI) {
|
||||
if (!printAliasInstr(MI, STI, O) && !printSparcAliasInstr(MI, STI, O))
|
||||
printInstruction(MI, STI, O);
|
||||
printAnnotation(O, Annot);
|
||||
}
|
||||
|
||||
bool SparcInstPrinter::printSparcAliasInstr(const MCInst *MI,
|
||||
const MCSubtargetInfo &STI,
|
||||
raw_ostream &O) {
|
||||
switch (MI->getOpcode()) {
|
||||
default: return false;
|
||||
case SP::JMPLrr:
|
||||
case SP::JMPLri: {
|
||||
if (MI->getNumOperands() != 3)
|
||||
return false;
|
||||
if (!MI->getOperand(0).isReg())
|
||||
return false;
|
||||
switch (MI->getOperand(0).getReg()) {
|
||||
default: return false;
|
||||
case SP::G0: // jmp $addr | ret | retl
|
||||
if (MI->getOperand(2).isImm() &&
|
||||
MI->getOperand(2).getImm() == 8) {
|
||||
switch(MI->getOperand(1).getReg()) {
|
||||
default: break;
|
||||
case SP::I7: O << "\tret"; return true;
|
||||
case SP::O7: O << "\tretl"; return true;
|
||||
}
|
||||
}
|
||||
O << "\tjmp "; printMemOperand(MI, 1, STI, O);
|
||||
return true;
|
||||
case SP::O7: // call $addr
|
||||
O << "\tcall "; printMemOperand(MI, 1, STI, O);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
case SP::V9FCMPS: case SP::V9FCMPD: case SP::V9FCMPQ:
|
||||
case SP::V9FCMPES: case SP::V9FCMPED: case SP::V9FCMPEQ: {
|
||||
if (isV9(STI)
|
||||
|| (MI->getNumOperands() != 3)
|
||||
|| (!MI->getOperand(0).isReg())
|
||||
|| (MI->getOperand(0).getReg() != SP::FCC0))
|
||||
return false;
|
||||
// if V8, skip printing %fcc0.
|
||||
switch(MI->getOpcode()) {
|
||||
default:
|
||||
case SP::V9FCMPS: O << "\tfcmps "; break;
|
||||
case SP::V9FCMPD: O << "\tfcmpd "; break;
|
||||
case SP::V9FCMPQ: O << "\tfcmpq "; break;
|
||||
case SP::V9FCMPES: O << "\tfcmpes "; break;
|
||||
case SP::V9FCMPED: O << "\tfcmped "; break;
|
||||
case SP::V9FCMPEQ: O << "\tfcmpeq "; break;
|
||||
}
|
||||
printOperand(MI, 1, STI, O);
|
||||
O << ", ";
|
||||
printOperand(MI, 2, STI, O);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SparcInstPrinter::printOperand(const MCInst *MI, int opNum,
|
||||
const MCSubtargetInfo &STI,
|
||||
raw_ostream &O) {
|
||||
const MCOperand &MO = MI->getOperand (opNum);
|
||||
|
||||
if (MO.isReg()) {
|
||||
printRegName(O, MO.getReg());
|
||||
return ;
|
||||
}
|
||||
|
||||
if (MO.isImm()) {
|
||||
switch (MI->getOpcode()) {
|
||||
default:
|
||||
O << (int)MO.getImm();
|
||||
return;
|
||||
|
||||
case SP::TICCri: // Fall through
|
||||
case SP::TICCrr: // Fall through
|
||||
case SP::TRAPri: // Fall through
|
||||
case SP::TRAPrr: // Fall through
|
||||
case SP::TXCCri: // Fall through
|
||||
case SP::TXCCrr: // Fall through
|
||||
// Only seven-bit values up to 127.
|
||||
O << ((int) MO.getImm() & 0x7f);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
assert(MO.isExpr() && "Unknown operand kind in printOperand");
|
||||
MO.getExpr()->print(O, &MAI);
|
||||
}
|
||||
|
||||
void SparcInstPrinter::printMemOperand(const MCInst *MI, int opNum,
|
||||
const MCSubtargetInfo &STI,
|
||||
raw_ostream &O, const char *Modifier) {
|
||||
printOperand(MI, opNum, STI, O);
|
||||
|
||||
// If this is an ADD operand, emit it like normal operands.
|
||||
if (Modifier && !strcmp(Modifier, "arith")) {
|
||||
O << ", ";
|
||||
printOperand(MI, opNum+1, STI, O);
|
||||
return;
|
||||
}
|
||||
const MCOperand &MO = MI->getOperand(opNum+1);
|
||||
|
||||
if (MO.isReg() && MO.getReg() == SP::G0)
|
||||
return; // don't print "+%g0"
|
||||
if (MO.isImm() && MO.getImm() == 0)
|
||||
return; // don't print "+0"
|
||||
|
||||
O << "+";
|
||||
|
||||
printOperand(MI, opNum+1, STI, O);
|
||||
}
|
||||
|
||||
void SparcInstPrinter::printCCOperand(const MCInst *MI, int opNum,
|
||||
const MCSubtargetInfo &STI,
|
||||
raw_ostream &O) {
|
||||
int CC = (int)MI->getOperand(opNum).getImm();
|
||||
switch (MI->getOpcode()) {
|
||||
default: break;
|
||||
case SP::FBCOND:
|
||||
case SP::FBCONDA:
|
||||
case SP::BPFCC:
|
||||
case SP::BPFCCA:
|
||||
case SP::BPFCCNT:
|
||||
case SP::BPFCCANT:
|
||||
case SP::MOVFCCrr: case SP::V9MOVFCCrr:
|
||||
case SP::MOVFCCri: case SP::V9MOVFCCri:
|
||||
case SP::FMOVS_FCC: case SP::V9FMOVS_FCC:
|
||||
case SP::FMOVD_FCC: case SP::V9FMOVD_FCC:
|
||||
case SP::FMOVQ_FCC: case SP::V9FMOVQ_FCC:
|
||||
// Make sure CC is a fp conditional flag.
|
||||
CC = (CC < 16) ? (CC + 16) : CC;
|
||||
break;
|
||||
case SP::CBCOND:
|
||||
case SP::CBCONDA:
|
||||
// Make sure CC is a cp conditional flag.
|
||||
CC = (CC < 32) ? (CC + 32) : CC;
|
||||
break;
|
||||
}
|
||||
O << SPARCCondCodeToString((SPCC::CondCodes)CC);
|
||||
}
|
||||
|
||||
bool SparcInstPrinter::printGetPCX(const MCInst *MI, unsigned opNum,
|
||||
const MCSubtargetInfo &STI,
|
||||
raw_ostream &O) {
|
||||
llvm_unreachable("FIXME: Implement SparcInstPrinter::printGetPCX.");
|
||||
return true;
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
//===-- SparcInstPrinter.h - Convert Sparc MCInst to assembly syntax ------===//
|
||||
//
|
||||
// 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 Sparc MCInst to a .s file.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIB_TARGET_SPARC_INSTPRINTER_SPARCINSTPRINTER_H
|
||||
#define LLVM_LIB_TARGET_SPARC_INSTPRINTER_SPARCINSTPRINTER_H
|
||||
|
||||
#include "llvm/MC/MCInstPrinter.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class SparcInstPrinter : public MCInstPrinter {
|
||||
public:
|
||||
SparcInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
|
||||
const MCRegisterInfo &MRI)
|
||||
: MCInstPrinter(MAI, MII, MRI) {}
|
||||
|
||||
void printRegName(raw_ostream &OS, unsigned RegNo) const override;
|
||||
void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot,
|
||||
const MCSubtargetInfo &STI) override;
|
||||
bool printSparcAliasInstr(const MCInst *MI, const MCSubtargetInfo &STI,
|
||||
raw_ostream &OS);
|
||||
bool isV9(const MCSubtargetInfo &STI) const;
|
||||
|
||||
// Autogenerated by tblgen.
|
||||
void printInstruction(const MCInst *MI, const MCSubtargetInfo &STI,
|
||||
raw_ostream &O);
|
||||
bool printAliasInstr(const MCInst *MI, const MCSubtargetInfo &STI,
|
||||
raw_ostream &O);
|
||||
void printCustomAliasOperand(const MCInst *MI, unsigned OpIdx,
|
||||
unsigned PrintMethodIdx,
|
||||
const MCSubtargetInfo &STI, raw_ostream &O);
|
||||
static const char *getRegisterName(unsigned RegNo);
|
||||
|
||||
void printOperand(const MCInst *MI, int opNum, const MCSubtargetInfo &STI,
|
||||
raw_ostream &OS);
|
||||
void printMemOperand(const MCInst *MI, int opNum, const MCSubtargetInfo &STI,
|
||||
raw_ostream &OS, const char *Modifier = nullptr);
|
||||
void printCCOperand(const MCInst *MI, int opNum, const MCSubtargetInfo &STI,
|
||||
raw_ostream &OS);
|
||||
bool printGetPCX(const MCInst *MI, unsigned OpNo, const MCSubtargetInfo &STI,
|
||||
raw_ostream &OS);
|
||||
};
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
36
external/llvm/lib/Target/Sparc/LLVMBuild.txt
vendored
36
external/llvm/lib/Target/Sparc/LLVMBuild.txt
vendored
@ -1,36 +0,0 @@
|
||||
;===- ./lib/Target/Sparc/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 = Sparc
|
||||
parent = Target
|
||||
has_asmparser = 1
|
||||
has_asmprinter = 1
|
||||
has_disassembler = 1
|
||||
has_jit = 1
|
||||
|
||||
[component_1]
|
||||
type = Library
|
||||
name = SparcCodeGen
|
||||
parent = Sparc
|
||||
required_libraries = AsmPrinter CodeGen Core MC SelectionDAG SparcAsmPrinter
|
||||
SparcDesc SparcInfo Support Target
|
||||
add_to_library_groups = Sparc
|
68
external/llvm/lib/Target/Sparc/LeonFeatures.td
vendored
68
external/llvm/lib/Target/Sparc/LeonFeatures.td
vendored
@ -1,68 +0,0 @@
|
||||
//===-- LeonFeatures.td - Describe the Leon Features -------*- tablegen -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// UMAC and SMAC support for LEON3 and LEON4 processors.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
//support to casa instruction; for leon3 subtarget only
|
||||
def UMACSMACSupport : SubtargetFeature<
|
||||
"hasumacsmac",
|
||||
"HasUmacSmac",
|
||||
"true",
|
||||
"Enable UMAC and SMAC for LEON3 and LEON4 processors"
|
||||
>;
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// CASA Support differs between LEON3-FT GR712RC and LEON3-FT UT699
|
||||
// We need to have the option to switch this on and off.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
//support to casa instruction; for leon3 subtarget only
|
||||
def LeonCASA : SubtargetFeature<
|
||||
"hasleoncasa",
|
||||
"HasLeonCasa",
|
||||
"true",
|
||||
"Enable CASA instruction for LEON3 and LEON4 processors"
|
||||
>;
|
||||
|
||||
|
||||
def ReplaceSDIV : SubtargetFeature<
|
||||
"replacesdiv",
|
||||
"PerformSDIVReplace",
|
||||
"true",
|
||||
"AT697E erratum fix: Do not emit SDIV, emit SDIVCC instead"
|
||||
>;
|
||||
|
||||
def InsertNOPLoad: SubtargetFeature<
|
||||
"insertnopload",
|
||||
"InsertNOPLoad",
|
||||
"true",
|
||||
"LEON3 erratum fix: Insert a NOP instruction after every single-cycle load instruction when the next instruction is another load/store instruction"
|
||||
>;
|
||||
|
||||
def DetectRoundChange : SubtargetFeature<
|
||||
"detectroundchange",
|
||||
"DetectRoundChange",
|
||||
"true",
|
||||
"LEON3 erratum detection: Detects any rounding mode change "
|
||||
"request: use only the round-to-nearest rounding mode"
|
||||
>;
|
||||
|
||||
def FixAllFDIVSQRT : SubtargetFeature<
|
||||
"fixallfdivsqrt",
|
||||
"FixAllFDIVSQRT",
|
||||
"true",
|
||||
"LEON erratum fix: Fix FDIVS/FDIVD/FSQRTS/FSQRTD instructions with NOPs and floating-point store"
|
||||
>;
|
158
external/llvm/lib/Target/Sparc/LeonPasses.cpp
vendored
158
external/llvm/lib/Target/Sparc/LeonPasses.cpp
vendored
@ -1,158 +0,0 @@
|
||||
//===------ LeonPasses.cpp - Define passes specific to LEON ---------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "LeonPasses.h"
|
||||
#include "llvm/CodeGen/ISDOpcodes.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/IR/DiagnosticInfo.h"
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
using namespace llvm;
|
||||
|
||||
LEONMachineFunctionPass::LEONMachineFunctionPass(char &ID)
|
||||
: MachineFunctionPass(ID) {}
|
||||
|
||||
//*****************************************************************************
|
||||
//**** InsertNOPLoad pass
|
||||
//*****************************************************************************
|
||||
// This pass fixes the incorrectly working Load instructions that exists for
|
||||
// some earlier versions of the LEON processor line. NOP instructions must
|
||||
// be inserted after the load instruction to ensure that the Load instruction
|
||||
// behaves as expected for these processors.
|
||||
//
|
||||
// This pass inserts a NOP after any LD or LDF instruction.
|
||||
//
|
||||
char InsertNOPLoad::ID = 0;
|
||||
|
||||
InsertNOPLoad::InsertNOPLoad() : LEONMachineFunctionPass(ID) {}
|
||||
|
||||
bool InsertNOPLoad::runOnMachineFunction(MachineFunction &MF) {
|
||||
Subtarget = &MF.getSubtarget<SparcSubtarget>();
|
||||
const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
|
||||
DebugLoc DL = DebugLoc();
|
||||
|
||||
bool Modified = false;
|
||||
for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) {
|
||||
MachineBasicBlock &MBB = *MFI;
|
||||
for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) {
|
||||
MachineInstr &MI = *MBBI;
|
||||
unsigned Opcode = MI.getOpcode();
|
||||
if (Opcode >= SP::LDDArr && Opcode <= SP::LDrr) {
|
||||
MachineBasicBlock::iterator NMBBI = std::next(MBBI);
|
||||
BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP));
|
||||
Modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Modified;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
//**** DetectRoundChange pass
|
||||
//*****************************************************************************
|
||||
// To prevent any explicit change of the default rounding mode, this pass
|
||||
// detects any call of the fesetround function.
|
||||
// A warning is generated to ensure the user knows this has happened.
|
||||
//
|
||||
// Detects an erratum in UT699 LEON 3 processor
|
||||
|
||||
char DetectRoundChange::ID = 0;
|
||||
|
||||
DetectRoundChange::DetectRoundChange() : LEONMachineFunctionPass(ID) {}
|
||||
|
||||
bool DetectRoundChange::runOnMachineFunction(MachineFunction &MF) {
|
||||
Subtarget = &MF.getSubtarget<SparcSubtarget>();
|
||||
|
||||
bool Modified = false;
|
||||
for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) {
|
||||
MachineBasicBlock &MBB = *MFI;
|
||||
for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) {
|
||||
MachineInstr &MI = *MBBI;
|
||||
unsigned Opcode = MI.getOpcode();
|
||||
if (Opcode == SP::CALL && MI.getNumOperands() > 0) {
|
||||
MachineOperand &MO = MI.getOperand(0);
|
||||
|
||||
if (MO.isGlobal()) {
|
||||
StringRef FuncName = MO.getGlobal()->getName();
|
||||
if (FuncName.compare_lower("fesetround") == 0) {
|
||||
errs() << "Error: You are using the detectroundchange "
|
||||
"option to detect rounding changes that will "
|
||||
"cause LEON errata. The only way to fix this "
|
||||
"is to remove the call to fesetround from "
|
||||
"the source code.\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Modified;
|
||||
}
|
||||
|
||||
//*****************************************************************************
|
||||
//**** FixAllFDIVSQRT pass
|
||||
//*****************************************************************************
|
||||
// This pass fixes the incorrectly working FDIVx and FSQRTx instructions that
|
||||
// exist for some earlier versions of the LEON processor line. Five NOP
|
||||
// instructions need to be inserted after these instructions to ensure the
|
||||
// correct result is placed in the destination registers before they are used.
|
||||
//
|
||||
// This pass implements two fixes:
|
||||
// 1) fixing the FSQRTS and FSQRTD instructions.
|
||||
// 2) fixing the FDIVS and FDIVD instructions.
|
||||
//
|
||||
// FSQRTS and FDIVS are converted to FDIVD and FSQRTD respectively earlier in
|
||||
// the pipeline when this option is enabled, so this pass needs only to deal
|
||||
// with the changes that still need implementing for the "double" versions
|
||||
// of these instructions.
|
||||
//
|
||||
char FixAllFDIVSQRT::ID = 0;
|
||||
|
||||
FixAllFDIVSQRT::FixAllFDIVSQRT() : LEONMachineFunctionPass(ID) {}
|
||||
|
||||
bool FixAllFDIVSQRT::runOnMachineFunction(MachineFunction &MF) {
|
||||
Subtarget = &MF.getSubtarget<SparcSubtarget>();
|
||||
const TargetInstrInfo &TII = *Subtarget->getInstrInfo();
|
||||
DebugLoc DL = DebugLoc();
|
||||
|
||||
bool Modified = false;
|
||||
for (auto MFI = MF.begin(), E = MF.end(); MFI != E; ++MFI) {
|
||||
MachineBasicBlock &MBB = *MFI;
|
||||
for (auto MBBI = MBB.begin(), E = MBB.end(); MBBI != E; ++MBBI) {
|
||||
MachineInstr &MI = *MBBI;
|
||||
unsigned Opcode = MI.getOpcode();
|
||||
|
||||
// Note: FDIVS and FSQRTS cannot be generated when this erratum fix is
|
||||
// switched on so we don't need to check for them here. They will
|
||||
// already have been converted to FSQRTD or FDIVD earlier in the
|
||||
// pipeline.
|
||||
if (Opcode == SP::FSQRTD || Opcode == SP::FDIVD) {
|
||||
for (int InsertedCount = 0; InsertedCount < 5; InsertedCount++)
|
||||
BuildMI(MBB, MBBI, DL, TII.get(SP::NOP));
|
||||
|
||||
MachineBasicBlock::iterator NMBBI = std::next(MBBI);
|
||||
for (int InsertedCount = 0; InsertedCount < 28; InsertedCount++)
|
||||
BuildMI(MBB, NMBBI, DL, TII.get(SP::NOP));
|
||||
|
||||
Modified = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Modified;
|
||||
}
|
88
external/llvm/lib/Target/Sparc/LeonPasses.h
vendored
88
external/llvm/lib/Target/Sparc/LeonPasses.h
vendored
@ -1,88 +0,0 @@
|
||||
//===------- LeonPasses.h - Define passes specific to LEON ----------------===//
|
||||
//
|
||||
// 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_SPARC_LEON_PASSES_H
|
||||
#define LLVM_LIB_TARGET_SPARC_LEON_PASSES_H
|
||||
|
||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||
#include "llvm/CodeGen/Passes.h"
|
||||
|
||||
#include "Sparc.h"
|
||||
#include "SparcSubtarget.h"
|
||||
|
||||
namespace llvm {
|
||||
class LLVM_LIBRARY_VISIBILITY LEONMachineFunctionPass
|
||||
: public MachineFunctionPass {
|
||||
protected:
|
||||
const SparcSubtarget *Subtarget;
|
||||
const int LAST_OPERAND = -1;
|
||||
|
||||
// this vector holds free registers that we allocate in groups for some of the
|
||||
// LEON passes
|
||||
std::vector<int> UsedRegisters;
|
||||
|
||||
protected:
|
||||
LEONMachineFunctionPass(char &ID);
|
||||
|
||||
int GetRegIndexForOperand(MachineInstr &MI, int OperandIndex);
|
||||
void clearUsedRegisterList() { UsedRegisters.clear(); }
|
||||
|
||||
void markRegisterUsed(int registerIndex) {
|
||||
UsedRegisters.push_back(registerIndex);
|
||||
}
|
||||
int getUnusedFPRegister(MachineRegisterInfo &MRI);
|
||||
};
|
||||
|
||||
class LLVM_LIBRARY_VISIBILITY InsertNOPLoad : public LEONMachineFunctionPass {
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
InsertNOPLoad();
|
||||
bool runOnMachineFunction(MachineFunction &MF) override;
|
||||
|
||||
StringRef getPassName() const override {
|
||||
return "InsertNOPLoad: Erratum Fix LBR35: insert a NOP instruction after "
|
||||
"every single-cycle load instruction when the next instruction is "
|
||||
"another load/store instruction";
|
||||
}
|
||||
};
|
||||
|
||||
class LLVM_LIBRARY_VISIBILITY DetectRoundChange
|
||||
: public LEONMachineFunctionPass {
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
DetectRoundChange();
|
||||
bool runOnMachineFunction(MachineFunction &MF) override;
|
||||
|
||||
StringRef getPassName() const override {
|
||||
return "DetectRoundChange: Leon erratum detection: detect any rounding "
|
||||
"mode change request: use only the round-to-nearest rounding mode";
|
||||
}
|
||||
};
|
||||
|
||||
class LLVM_LIBRARY_VISIBILITY FixAllFDIVSQRT : public LEONMachineFunctionPass {
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
FixAllFDIVSQRT();
|
||||
bool runOnMachineFunction(MachineFunction &MF) override;
|
||||
|
||||
StringRef getPassName() const override {
|
||||
return "FixAllFDIVSQRT: Erratum Fix LBR34: fix FDIVS/FDIVD/FSQRTS/FSQRTD "
|
||||
"instructions with NOPs and floating-point store";
|
||||
}
|
||||
};
|
||||
} // namespace llvm
|
||||
|
||||
#endif // LLVM_LIB_TARGET_SPARC_LEON_PASSES_H
|
@ -1,9 +0,0 @@
|
||||
add_llvm_library(LLVMSparcDesc
|
||||
SparcAsmBackend.cpp
|
||||
SparcELFObjectWriter.cpp
|
||||
SparcMCAsmInfo.cpp
|
||||
SparcMCCodeEmitter.cpp
|
||||
SparcMCTargetDesc.cpp
|
||||
SparcMCExpr.cpp
|
||||
SparcTargetStreamer.cpp
|
||||
)
|
@ -1,23 +0,0 @@
|
||||
;===- ./lib/Target/Sparc/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 = SparcDesc
|
||||
parent = Sparc
|
||||
required_libraries = MC SparcAsmPrinter SparcInfo Support
|
||||
add_to_library_groups = Sparc
|
@ -1,309 +0,0 @@
|
||||
//===-- SparcAsmBackend.cpp - Sparc 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/SparcFixupKinds.h"
|
||||
#include "MCTargetDesc/SparcMCTargetDesc.h"
|
||||
#include "llvm/MC/MCAsmBackend.h"
|
||||
#include "llvm/MC/MCELFObjectWriter.h"
|
||||
#include "llvm/MC/MCExpr.h"
|
||||
#include "llvm/MC/MCFixupKindInfo.h"
|
||||
#include "llvm/MC/MCObjectWriter.h"
|
||||
#include "llvm/MC/MCSubtargetInfo.h"
|
||||
#include "llvm/MC/MCValue.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
static unsigned 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:
|
||||
return Value;
|
||||
|
||||
case Sparc::fixup_sparc_wplt30:
|
||||
case Sparc::fixup_sparc_call30:
|
||||
return (Value >> 2) & 0x3fffffff;
|
||||
|
||||
case Sparc::fixup_sparc_br22:
|
||||
return (Value >> 2) & 0x3fffff;
|
||||
|
||||
case Sparc::fixup_sparc_br19:
|
||||
return (Value >> 2) & 0x7ffff;
|
||||
|
||||
case Sparc::fixup_sparc_br16_2:
|
||||
return (Value >> 2) & 0xc000;
|
||||
|
||||
case Sparc::fixup_sparc_br16_14:
|
||||
return (Value >> 2) & 0x3fff;
|
||||
|
||||
case Sparc::fixup_sparc_pc22:
|
||||
case Sparc::fixup_sparc_got22:
|
||||
case Sparc::fixup_sparc_tls_gd_hi22:
|
||||
case Sparc::fixup_sparc_tls_ldm_hi22:
|
||||
case Sparc::fixup_sparc_tls_ie_hi22:
|
||||
case Sparc::fixup_sparc_hi22:
|
||||
return (Value >> 10) & 0x3fffff;
|
||||
|
||||
case Sparc::fixup_sparc_pc10:
|
||||
case Sparc::fixup_sparc_got10:
|
||||
case Sparc::fixup_sparc_tls_gd_lo10:
|
||||
case Sparc::fixup_sparc_tls_ldm_lo10:
|
||||
case Sparc::fixup_sparc_tls_ie_lo10:
|
||||
case Sparc::fixup_sparc_lo10:
|
||||
return Value & 0x3ff;
|
||||
|
||||
case Sparc::fixup_sparc_h44:
|
||||
return (Value >> 22) & 0x3fffff;
|
||||
|
||||
case Sparc::fixup_sparc_m44:
|
||||
return (Value >> 12) & 0x3ff;
|
||||
|
||||
case Sparc::fixup_sparc_l44:
|
||||
return Value & 0xfff;
|
||||
|
||||
case Sparc::fixup_sparc_hh:
|
||||
return (Value >> 42) & 0x3fffff;
|
||||
|
||||
case Sparc::fixup_sparc_hm:
|
||||
return (Value >> 32) & 0x3ff;
|
||||
|
||||
case Sparc::fixup_sparc_tls_ldo_hix22:
|
||||
case Sparc::fixup_sparc_tls_le_hix22:
|
||||
case Sparc::fixup_sparc_tls_ldo_lox10:
|
||||
case Sparc::fixup_sparc_tls_le_lox10:
|
||||
assert(Value == 0 && "Sparc TLS relocs expect zero Value");
|
||||
return 0;
|
||||
|
||||
case Sparc::fixup_sparc_tls_gd_add:
|
||||
case Sparc::fixup_sparc_tls_gd_call:
|
||||
case Sparc::fixup_sparc_tls_ldm_add:
|
||||
case Sparc::fixup_sparc_tls_ldm_call:
|
||||
case Sparc::fixup_sparc_tls_ldo_add:
|
||||
case Sparc::fixup_sparc_tls_ie_ld:
|
||||
case Sparc::fixup_sparc_tls_ie_ldx:
|
||||
case Sparc::fixup_sparc_tls_ie_add:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
class SparcAsmBackend : public MCAsmBackend {
|
||||
protected:
|
||||
const Target &TheTarget;
|
||||
bool IsLittleEndian;
|
||||
bool Is64Bit;
|
||||
|
||||
public:
|
||||
SparcAsmBackend(const Target &T)
|
||||
: MCAsmBackend(), TheTarget(T),
|
||||
IsLittleEndian(StringRef(TheTarget.getName()) == "sparcel"),
|
||||
Is64Bit(StringRef(TheTarget.getName()) == "sparcv9") {}
|
||||
|
||||
unsigned getNumFixupKinds() const override {
|
||||
return Sparc::NumTargetFixupKinds;
|
||||
}
|
||||
|
||||
const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override {
|
||||
const static MCFixupKindInfo InfosBE[Sparc::NumTargetFixupKinds] = {
|
||||
// name offset bits flags
|
||||
{ "fixup_sparc_call30", 2, 30, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_sparc_br22", 10, 22, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_sparc_br19", 13, 19, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_sparc_br16_2", 10, 2, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_sparc_br16_14", 18, 14, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_sparc_hi22", 10, 22, 0 },
|
||||
{ "fixup_sparc_lo10", 22, 10, 0 },
|
||||
{ "fixup_sparc_h44", 10, 22, 0 },
|
||||
{ "fixup_sparc_m44", 22, 10, 0 },
|
||||
{ "fixup_sparc_l44", 20, 12, 0 },
|
||||
{ "fixup_sparc_hh", 10, 22, 0 },
|
||||
{ "fixup_sparc_hm", 22, 10, 0 },
|
||||
{ "fixup_sparc_pc22", 10, 22, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_sparc_pc10", 22, 10, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_sparc_got22", 10, 22, 0 },
|
||||
{ "fixup_sparc_got10", 22, 10, 0 },
|
||||
{ "fixup_sparc_wplt30", 2, 30, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_sparc_tls_gd_hi22", 10, 22, 0 },
|
||||
{ "fixup_sparc_tls_gd_lo10", 22, 10, 0 },
|
||||
{ "fixup_sparc_tls_gd_add", 0, 0, 0 },
|
||||
{ "fixup_sparc_tls_gd_call", 0, 0, 0 },
|
||||
{ "fixup_sparc_tls_ldm_hi22", 10, 22, 0 },
|
||||
{ "fixup_sparc_tls_ldm_lo10", 22, 10, 0 },
|
||||
{ "fixup_sparc_tls_ldm_add", 0, 0, 0 },
|
||||
{ "fixup_sparc_tls_ldm_call", 0, 0, 0 },
|
||||
{ "fixup_sparc_tls_ldo_hix22", 10, 22, 0 },
|
||||
{ "fixup_sparc_tls_ldo_lox10", 22, 10, 0 },
|
||||
{ "fixup_sparc_tls_ldo_add", 0, 0, 0 },
|
||||
{ "fixup_sparc_tls_ie_hi22", 10, 22, 0 },
|
||||
{ "fixup_sparc_tls_ie_lo10", 22, 10, 0 },
|
||||
{ "fixup_sparc_tls_ie_ld", 0, 0, 0 },
|
||||
{ "fixup_sparc_tls_ie_ldx", 0, 0, 0 },
|
||||
{ "fixup_sparc_tls_ie_add", 0, 0, 0 },
|
||||
{ "fixup_sparc_tls_le_hix22", 0, 0, 0 },
|
||||
{ "fixup_sparc_tls_le_lox10", 0, 0, 0 }
|
||||
};
|
||||
|
||||
const static MCFixupKindInfo InfosLE[Sparc::NumTargetFixupKinds] = {
|
||||
// name offset bits flags
|
||||
{ "fixup_sparc_call30", 0, 30, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_sparc_br22", 0, 22, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_sparc_br19", 0, 19, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_sparc_br16_2", 20, 2, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_sparc_br16_14", 0, 14, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_sparc_hi22", 0, 22, 0 },
|
||||
{ "fixup_sparc_lo10", 0, 10, 0 },
|
||||
{ "fixup_sparc_h44", 0, 22, 0 },
|
||||
{ "fixup_sparc_m44", 0, 10, 0 },
|
||||
{ "fixup_sparc_l44", 0, 12, 0 },
|
||||
{ "fixup_sparc_hh", 0, 22, 0 },
|
||||
{ "fixup_sparc_hm", 0, 10, 0 },
|
||||
{ "fixup_sparc_pc22", 0, 22, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_sparc_pc10", 0, 10, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_sparc_got22", 0, 22, 0 },
|
||||
{ "fixup_sparc_got10", 0, 10, 0 },
|
||||
{ "fixup_sparc_wplt30", 0, 30, MCFixupKindInfo::FKF_IsPCRel },
|
||||
{ "fixup_sparc_tls_gd_hi22", 0, 22, 0 },
|
||||
{ "fixup_sparc_tls_gd_lo10", 0, 10, 0 },
|
||||
{ "fixup_sparc_tls_gd_add", 0, 0, 0 },
|
||||
{ "fixup_sparc_tls_gd_call", 0, 0, 0 },
|
||||
{ "fixup_sparc_tls_ldm_hi22", 0, 22, 0 },
|
||||
{ "fixup_sparc_tls_ldm_lo10", 0, 10, 0 },
|
||||
{ "fixup_sparc_tls_ldm_add", 0, 0, 0 },
|
||||
{ "fixup_sparc_tls_ldm_call", 0, 0, 0 },
|
||||
{ "fixup_sparc_tls_ldo_hix22", 0, 22, 0 },
|
||||
{ "fixup_sparc_tls_ldo_lox10", 0, 10, 0 },
|
||||
{ "fixup_sparc_tls_ldo_add", 0, 0, 0 },
|
||||
{ "fixup_sparc_tls_ie_hi22", 0, 22, 0 },
|
||||
{ "fixup_sparc_tls_ie_lo10", 0, 10, 0 },
|
||||
{ "fixup_sparc_tls_ie_ld", 0, 0, 0 },
|
||||
{ "fixup_sparc_tls_ie_ldx", 0, 0, 0 },
|
||||
{ "fixup_sparc_tls_ie_add", 0, 0, 0 },
|
||||
{ "fixup_sparc_tls_le_hix22", 0, 0, 0 },
|
||||
{ "fixup_sparc_tls_le_lox10", 0, 0, 0 }
|
||||
};
|
||||
|
||||
if (Kind < FirstTargetFixupKind)
|
||||
return MCAsmBackend::getFixupKindInfo(Kind);
|
||||
|
||||
assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
|
||||
"Invalid kind!");
|
||||
if (IsLittleEndian)
|
||||
return InfosLE[Kind - FirstTargetFixupKind];
|
||||
|
||||
return InfosBE[Kind - FirstTargetFixupKind];
|
||||
}
|
||||
|
||||
bool shouldForceRelocation(const MCAssembler &Asm, const MCFixup &Fixup,
|
||||
const MCValue &Target) override {
|
||||
switch ((Sparc::Fixups)Fixup.getKind()) {
|
||||
default:
|
||||
return false;
|
||||
case Sparc::fixup_sparc_wplt30:
|
||||
if (Target.getSymA()->getSymbol().isTemporary())
|
||||
return false;
|
||||
LLVM_FALLTHROUGH;
|
||||
case Sparc::fixup_sparc_tls_gd_hi22:
|
||||
case Sparc::fixup_sparc_tls_gd_lo10:
|
||||
case Sparc::fixup_sparc_tls_gd_add:
|
||||
case Sparc::fixup_sparc_tls_gd_call:
|
||||
case Sparc::fixup_sparc_tls_ldm_hi22:
|
||||
case Sparc::fixup_sparc_tls_ldm_lo10:
|
||||
case Sparc::fixup_sparc_tls_ldm_add:
|
||||
case Sparc::fixup_sparc_tls_ldm_call:
|
||||
case Sparc::fixup_sparc_tls_ldo_hix22:
|
||||
case Sparc::fixup_sparc_tls_ldo_lox10:
|
||||
case Sparc::fixup_sparc_tls_ldo_add:
|
||||
case Sparc::fixup_sparc_tls_ie_hi22:
|
||||
case Sparc::fixup_sparc_tls_ie_lo10:
|
||||
case Sparc::fixup_sparc_tls_ie_ld:
|
||||
case Sparc::fixup_sparc_tls_ie_ldx:
|
||||
case Sparc::fixup_sparc_tls_ie_add:
|
||||
case Sparc::fixup_sparc_tls_le_hix22:
|
||||
case Sparc::fixup_sparc_tls_le_lox10:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool mayNeedRelaxation(const MCInst &Inst) const override {
|
||||
// FIXME.
|
||||
return false;
|
||||
}
|
||||
|
||||
/// fixupNeedsRelaxation - Target specific predicate for whether a given
|
||||
/// fixup requires the associated instruction to be relaxed.
|
||||
bool fixupNeedsRelaxation(const MCFixup &Fixup,
|
||||
uint64_t Value,
|
||||
const MCRelaxableFragment *DF,
|
||||
const MCAsmLayout &Layout) const override {
|
||||
// FIXME.
|
||||
llvm_unreachable("fixupNeedsRelaxation() unimplemented");
|
||||
return false;
|
||||
}
|
||||
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 {
|
||||
// Cannot emit NOP with size not multiple of 32 bits.
|
||||
if (Count % 4 != 0)
|
||||
return false;
|
||||
|
||||
uint64_t NumNops = Count / 4;
|
||||
for (uint64_t i = 0; i != NumNops; ++i)
|
||||
OW->write32(0x01000000);
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class ELFSparcAsmBackend : public SparcAsmBackend {
|
||||
Triple::OSType OSType;
|
||||
public:
|
||||
ELFSparcAsmBackend(const Target &T, Triple::OSType OSType) :
|
||||
SparcAsmBackend(T), OSType(OSType) { }
|
||||
|
||||
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();
|
||||
|
||||
// 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 != 4; ++i) {
|
||||
unsigned Idx = IsLittleEndian ? i : 3 - i;
|
||||
Data[Offset + Idx] |= uint8_t((Value >> (i * 8)) & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<MCObjectWriter>
|
||||
createObjectWriter(raw_pwrite_stream &OS) const override {
|
||||
uint8_t OSABI = MCELFObjectTargetWriter::getOSABI(OSType);
|
||||
return createSparcELFObjectWriter(OS, Is64Bit, IsLittleEndian, OSABI);
|
||||
}
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
MCAsmBackend *llvm::createSparcAsmBackend(const Target &T,
|
||||
const MCSubtargetInfo &STI,
|
||||
const MCRegisterInfo &MRI,
|
||||
const MCTargetOptions &Options) {
|
||||
return new ELFSparcAsmBackend(T, STI.getTargetTriple().getOS());
|
||||
}
|
@ -1,140 +0,0 @@
|
||||
//===-- SparcELFObjectWriter.cpp - Sparc 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/SparcFixupKinds.h"
|
||||
#include "MCTargetDesc/SparcMCExpr.h"
|
||||
#include "MCTargetDesc/SparcMCTargetDesc.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/MC/MCELFObjectWriter.h"
|
||||
#include "llvm/MC/MCExpr.h"
|
||||
#include "llvm/MC/MCObjectWriter.h"
|
||||
#include "llvm/MC/MCValue.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
class SparcELFObjectWriter : public MCELFObjectTargetWriter {
|
||||
public:
|
||||
SparcELFObjectWriter(bool Is64Bit, uint8_t OSABI)
|
||||
: MCELFObjectTargetWriter(Is64Bit, OSABI,
|
||||
Is64Bit ? ELF::EM_SPARCV9 : ELF::EM_SPARC,
|
||||
/*HasRelocationAddend*/ true) {}
|
||||
|
||||
~SparcELFObjectWriter() override {}
|
||||
|
||||
protected:
|
||||
unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
|
||||
const MCFixup &Fixup, bool IsPCRel) const override;
|
||||
|
||||
bool needsRelocateWithSymbol(const MCSymbol &Sym,
|
||||
unsigned Type) const override;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
unsigned SparcELFObjectWriter::getRelocType(MCContext &Ctx,
|
||||
const MCValue &Target,
|
||||
const MCFixup &Fixup,
|
||||
bool IsPCRel) const {
|
||||
|
||||
if (const SparcMCExpr *SExpr = dyn_cast<SparcMCExpr>(Fixup.getValue())) {
|
||||
if (SExpr->getKind() == SparcMCExpr::VK_Sparc_R_DISP32)
|
||||
return ELF::R_SPARC_DISP32;
|
||||
}
|
||||
|
||||
if (IsPCRel) {
|
||||
switch((unsigned)Fixup.getKind()) {
|
||||
default:
|
||||
llvm_unreachable("Unimplemented fixup -> relocation");
|
||||
case FK_Data_1: return ELF::R_SPARC_DISP8;
|
||||
case FK_Data_2: return ELF::R_SPARC_DISP16;
|
||||
case FK_Data_4: return ELF::R_SPARC_DISP32;
|
||||
case FK_Data_8: return ELF::R_SPARC_DISP64;
|
||||
case Sparc::fixup_sparc_call30: return ELF::R_SPARC_WDISP30;
|
||||
case Sparc::fixup_sparc_br22: return ELF::R_SPARC_WDISP22;
|
||||
case Sparc::fixup_sparc_br19: return ELF::R_SPARC_WDISP19;
|
||||
case Sparc::fixup_sparc_pc22: return ELF::R_SPARC_PC22;
|
||||
case Sparc::fixup_sparc_pc10: return ELF::R_SPARC_PC10;
|
||||
case Sparc::fixup_sparc_wplt30: return ELF::R_SPARC_WPLT30;
|
||||
}
|
||||
}
|
||||
|
||||
switch((unsigned)Fixup.getKind()) {
|
||||
default:
|
||||
llvm_unreachable("Unimplemented fixup -> relocation");
|
||||
case FK_Data_1: return ELF::R_SPARC_8;
|
||||
case FK_Data_2: return ((Fixup.getOffset() % 2)
|
||||
? ELF::R_SPARC_UA16
|
||||
: ELF::R_SPARC_16);
|
||||
case FK_Data_4: return ((Fixup.getOffset() % 4)
|
||||
? ELF::R_SPARC_UA32
|
||||
: ELF::R_SPARC_32);
|
||||
case FK_Data_8: return ((Fixup.getOffset() % 8)
|
||||
? ELF::R_SPARC_UA64
|
||||
: ELF::R_SPARC_64);
|
||||
case Sparc::fixup_sparc_hi22: return ELF::R_SPARC_HI22;
|
||||
case Sparc::fixup_sparc_lo10: return ELF::R_SPARC_LO10;
|
||||
case Sparc::fixup_sparc_h44: return ELF::R_SPARC_H44;
|
||||
case Sparc::fixup_sparc_m44: return ELF::R_SPARC_M44;
|
||||
case Sparc::fixup_sparc_l44: return ELF::R_SPARC_L44;
|
||||
case Sparc::fixup_sparc_hh: return ELF::R_SPARC_HH22;
|
||||
case Sparc::fixup_sparc_hm: return ELF::R_SPARC_HM10;
|
||||
case Sparc::fixup_sparc_got22: return ELF::R_SPARC_GOT22;
|
||||
case Sparc::fixup_sparc_got10: return ELF::R_SPARC_GOT10;
|
||||
case Sparc::fixup_sparc_tls_gd_hi22: return ELF::R_SPARC_TLS_GD_HI22;
|
||||
case Sparc::fixup_sparc_tls_gd_lo10: return ELF::R_SPARC_TLS_GD_LO10;
|
||||
case Sparc::fixup_sparc_tls_gd_add: return ELF::R_SPARC_TLS_GD_ADD;
|
||||
case Sparc::fixup_sparc_tls_gd_call: return ELF::R_SPARC_TLS_GD_CALL;
|
||||
case Sparc::fixup_sparc_tls_ldm_hi22: return ELF::R_SPARC_TLS_LDM_HI22;
|
||||
case Sparc::fixup_sparc_tls_ldm_lo10: return ELF::R_SPARC_TLS_LDM_LO10;
|
||||
case Sparc::fixup_sparc_tls_ldm_add: return ELF::R_SPARC_TLS_LDM_ADD;
|
||||
case Sparc::fixup_sparc_tls_ldm_call: return ELF::R_SPARC_TLS_LDM_CALL;
|
||||
case Sparc::fixup_sparc_tls_ldo_hix22: return ELF::R_SPARC_TLS_LDO_HIX22;
|
||||
case Sparc::fixup_sparc_tls_ldo_lox10: return ELF::R_SPARC_TLS_LDO_LOX10;
|
||||
case Sparc::fixup_sparc_tls_ldo_add: return ELF::R_SPARC_TLS_LDO_ADD;
|
||||
case Sparc::fixup_sparc_tls_ie_hi22: return ELF::R_SPARC_TLS_IE_HI22;
|
||||
case Sparc::fixup_sparc_tls_ie_lo10: return ELF::R_SPARC_TLS_IE_LO10;
|
||||
case Sparc::fixup_sparc_tls_ie_ld: return ELF::R_SPARC_TLS_IE_LD;
|
||||
case Sparc::fixup_sparc_tls_ie_ldx: return ELF::R_SPARC_TLS_IE_LDX;
|
||||
case Sparc::fixup_sparc_tls_ie_add: return ELF::R_SPARC_TLS_IE_ADD;
|
||||
case Sparc::fixup_sparc_tls_le_hix22: return ELF::R_SPARC_TLS_LE_HIX22;
|
||||
case Sparc::fixup_sparc_tls_le_lox10: return ELF::R_SPARC_TLS_LE_LOX10;
|
||||
}
|
||||
|
||||
return ELF::R_SPARC_NONE;
|
||||
}
|
||||
|
||||
bool SparcELFObjectWriter::needsRelocateWithSymbol(const MCSymbol &Sym,
|
||||
unsigned Type) const {
|
||||
switch (Type) {
|
||||
default:
|
||||
return false;
|
||||
|
||||
// All relocations that use a GOT need a symbol, not an offset, as
|
||||
// the offset of the symbol within the section is irrelevant to
|
||||
// where the GOT entry is. Don't need to list all the TLS entries,
|
||||
// as they're all marked as requiring a symbol anyways.
|
||||
case ELF::R_SPARC_GOT10:
|
||||
case ELF::R_SPARC_GOT13:
|
||||
case ELF::R_SPARC_GOT22:
|
||||
case ELF::R_SPARC_GOTDATA_HIX22:
|
||||
case ELF::R_SPARC_GOTDATA_LOX10:
|
||||
case ELF::R_SPARC_GOTDATA_OP_HIX22:
|
||||
case ELF::R_SPARC_GOTDATA_OP_LOX10:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<MCObjectWriter>
|
||||
llvm::createSparcELFObjectWriter(raw_pwrite_stream &OS, bool Is64Bit,
|
||||
bool IsLittleEndian, uint8_t OSABI) {
|
||||
auto MOTW = llvm::make_unique<SparcELFObjectWriter>(Is64Bit, OSABI);
|
||||
return createELFObjectWriter(std::move(MOTW), OS, IsLittleEndian);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user