mirror of
https://github.com/opnsense/src.git
synced 2026-02-22 09:21:31 -05:00
all of the features in the current working draft of the upcoming C++ standard, provisionally named C++1y. The code generator's performance is greatly increased, and the loop auto-vectorizer is now enabled at -Os and -O2 in addition to -O3. The PowerPC backend has made several major improvements to code generation quality and compile time, and the X86, SPARC, ARM32, Aarch64 and SystemZ backends have all seen major feature work. Release notes for llvm and clang can be found here: <http://llvm.org/releases/3.4/docs/ReleaseNotes.html> <http://llvm.org/releases/3.4/tools/clang/docs/ReleaseNotes.html> MFC after: 1 month
239 lines
7.7 KiB
C++
239 lines
7.7 KiB
C++
//===-- SystemZAsmPrinter.cpp - SystemZ LLVM assembly printer -------------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Streams SystemZ assembly language and associated data, in the form of
|
|
// MCInsts and MCExprs respectively.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "SystemZAsmPrinter.h"
|
|
#include "InstPrinter/SystemZInstPrinter.h"
|
|
#include "SystemZConstantPoolValue.h"
|
|
#include "SystemZMCInstLower.h"
|
|
#include "llvm/CodeGen/MachineModuleInfoImpls.h"
|
|
#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
|
|
#include "llvm/MC/MCExpr.h"
|
|
#include "llvm/MC/MCInstBuilder.h"
|
|
#include "llvm/MC/MCStreamer.h"
|
|
#include "llvm/Support/TargetRegistry.h"
|
|
#include "llvm/Target/Mangler.h"
|
|
|
|
using namespace llvm;
|
|
|
|
// Return an RI instruction like MI with opcode Opcode, but with the
|
|
// GR64 register operands turned into GR32s.
|
|
static MCInst lowerRILow(const MachineInstr *MI, unsigned Opcode) {
|
|
if (MI->isCompare())
|
|
return MCInstBuilder(Opcode)
|
|
.addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
|
|
.addImm(MI->getOperand(1).getImm());
|
|
else
|
|
return MCInstBuilder(Opcode)
|
|
.addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
|
|
.addReg(SystemZMC::getRegAsGR32(MI->getOperand(1).getReg()))
|
|
.addImm(MI->getOperand(2).getImm());
|
|
}
|
|
|
|
// Return an RI instruction like MI with opcode Opcode, but with the
|
|
// GR64 register operands turned into GRH32s.
|
|
static MCInst lowerRIHigh(const MachineInstr *MI, unsigned Opcode) {
|
|
if (MI->isCompare())
|
|
return MCInstBuilder(Opcode)
|
|
.addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
|
|
.addImm(MI->getOperand(1).getImm());
|
|
else
|
|
return MCInstBuilder(Opcode)
|
|
.addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
|
|
.addReg(SystemZMC::getRegAsGRH32(MI->getOperand(1).getReg()))
|
|
.addImm(MI->getOperand(2).getImm());
|
|
}
|
|
|
|
// Return an RI instruction like MI with opcode Opcode, but with the
|
|
// R2 register turned into a GR64.
|
|
static MCInst lowerRIEfLow(const MachineInstr *MI, unsigned Opcode) {
|
|
return MCInstBuilder(Opcode)
|
|
.addReg(MI->getOperand(0).getReg())
|
|
.addReg(MI->getOperand(1).getReg())
|
|
.addReg(SystemZMC::getRegAsGR64(MI->getOperand(2).getReg()))
|
|
.addImm(MI->getOperand(3).getImm())
|
|
.addImm(MI->getOperand(4).getImm())
|
|
.addImm(MI->getOperand(5).getImm());
|
|
}
|
|
|
|
void SystemZAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
|
SystemZMCInstLower Lower(MF->getContext(), *this);
|
|
MCInst LoweredMI;
|
|
switch (MI->getOpcode()) {
|
|
case SystemZ::Return:
|
|
LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R14D);
|
|
break;
|
|
|
|
case SystemZ::CallBRASL:
|
|
LoweredMI = MCInstBuilder(SystemZ::BRASL)
|
|
.addReg(SystemZ::R14D)
|
|
.addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT));
|
|
break;
|
|
|
|
case SystemZ::CallBASR:
|
|
LoweredMI = MCInstBuilder(SystemZ::BASR)
|
|
.addReg(SystemZ::R14D)
|
|
.addReg(MI->getOperand(0).getReg());
|
|
break;
|
|
|
|
case SystemZ::CallJG:
|
|
LoweredMI = MCInstBuilder(SystemZ::JG)
|
|
.addExpr(Lower.getExpr(MI->getOperand(0), MCSymbolRefExpr::VK_PLT));
|
|
break;
|
|
|
|
case SystemZ::CallBR:
|
|
LoweredMI = MCInstBuilder(SystemZ::BR).addReg(SystemZ::R1D);
|
|
break;
|
|
|
|
case SystemZ::IILF64:
|
|
LoweredMI = MCInstBuilder(SystemZ::IILF)
|
|
.addReg(SystemZMC::getRegAsGR32(MI->getOperand(0).getReg()))
|
|
.addImm(MI->getOperand(2).getImm());
|
|
break;
|
|
|
|
case SystemZ::IIHF64:
|
|
LoweredMI = MCInstBuilder(SystemZ::IIHF)
|
|
.addReg(SystemZMC::getRegAsGRH32(MI->getOperand(0).getReg()))
|
|
.addImm(MI->getOperand(2).getImm());
|
|
break;
|
|
|
|
case SystemZ::RISBHH:
|
|
case SystemZ::RISBHL:
|
|
LoweredMI = lowerRIEfLow(MI, SystemZ::RISBHG);
|
|
break;
|
|
|
|
case SystemZ::RISBLH:
|
|
case SystemZ::RISBLL:
|
|
LoweredMI = lowerRIEfLow(MI, SystemZ::RISBLG);
|
|
break;
|
|
|
|
#define LOWER_LOW(NAME) \
|
|
case SystemZ::NAME##64: LoweredMI = lowerRILow(MI, SystemZ::NAME); break
|
|
|
|
LOWER_LOW(IILL);
|
|
LOWER_LOW(IILH);
|
|
LOWER_LOW(TMLL);
|
|
LOWER_LOW(TMLH);
|
|
LOWER_LOW(NILL);
|
|
LOWER_LOW(NILH);
|
|
LOWER_LOW(NILF);
|
|
LOWER_LOW(OILL);
|
|
LOWER_LOW(OILH);
|
|
LOWER_LOW(OILF);
|
|
LOWER_LOW(XILF);
|
|
|
|
#undef LOWER_LOW
|
|
|
|
#define LOWER_HIGH(NAME) \
|
|
case SystemZ::NAME##64: LoweredMI = lowerRIHigh(MI, SystemZ::NAME); break
|
|
|
|
LOWER_HIGH(IIHL);
|
|
LOWER_HIGH(IIHH);
|
|
LOWER_HIGH(TMHL);
|
|
LOWER_HIGH(TMHH);
|
|
LOWER_HIGH(NIHL);
|
|
LOWER_HIGH(NIHH);
|
|
LOWER_HIGH(NIHF);
|
|
LOWER_HIGH(OIHL);
|
|
LOWER_HIGH(OIHH);
|
|
LOWER_HIGH(OIHF);
|
|
LOWER_HIGH(XIHF);
|
|
|
|
#undef LOWER_HIGH
|
|
|
|
default:
|
|
Lower.lower(MI, LoweredMI);
|
|
break;
|
|
}
|
|
OutStreamer.EmitInstruction(LoweredMI);
|
|
}
|
|
|
|
// Convert a SystemZ-specific constant pool modifier into the associated
|
|
// MCSymbolRefExpr variant kind.
|
|
static MCSymbolRefExpr::VariantKind
|
|
getModifierVariantKind(SystemZCP::SystemZCPModifier Modifier) {
|
|
switch (Modifier) {
|
|
case SystemZCP::NTPOFF: return MCSymbolRefExpr::VK_NTPOFF;
|
|
}
|
|
llvm_unreachable("Invalid SystemCPModifier!");
|
|
}
|
|
|
|
void SystemZAsmPrinter::
|
|
EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
|
|
SystemZConstantPoolValue *ZCPV =
|
|
static_cast<SystemZConstantPoolValue*>(MCPV);
|
|
|
|
const MCExpr *Expr =
|
|
MCSymbolRefExpr::Create(getSymbol(ZCPV->getGlobalValue()),
|
|
getModifierVariantKind(ZCPV->getModifier()),
|
|
OutContext);
|
|
uint64_t Size = TM.getDataLayout()->getTypeAllocSize(ZCPV->getType());
|
|
|
|
OutStreamer.EmitValue(Expr, Size);
|
|
}
|
|
|
|
bool SystemZAsmPrinter::PrintAsmOperand(const MachineInstr *MI,
|
|
unsigned OpNo,
|
|
unsigned AsmVariant,
|
|
const char *ExtraCode,
|
|
raw_ostream &OS) {
|
|
if (ExtraCode && *ExtraCode == 'n') {
|
|
if (!MI->getOperand(OpNo).isImm())
|
|
return true;
|
|
OS << -int64_t(MI->getOperand(OpNo).getImm());
|
|
} else {
|
|
SystemZMCInstLower Lower(MF->getContext(), *this);
|
|
MCOperand MO(Lower.lowerOperand(MI->getOperand(OpNo)));
|
|
SystemZInstPrinter::printOperand(MO, OS);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool SystemZAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
|
|
unsigned OpNo,
|
|
unsigned AsmVariant,
|
|
const char *ExtraCode,
|
|
raw_ostream &OS) {
|
|
SystemZInstPrinter::printAddress(MI->getOperand(OpNo).getReg(),
|
|
MI->getOperand(OpNo + 1).getImm(),
|
|
MI->getOperand(OpNo + 2).getReg(), OS);
|
|
return false;
|
|
}
|
|
|
|
void SystemZAsmPrinter::EmitEndOfAsmFile(Module &M) {
|
|
if (Subtarget->isTargetELF()) {
|
|
const TargetLoweringObjectFileELF &TLOFELF =
|
|
static_cast<const TargetLoweringObjectFileELF &>(getObjFileLowering());
|
|
|
|
MachineModuleInfoELF &MMIELF = MMI->getObjFileInfo<MachineModuleInfoELF>();
|
|
|
|
// Output stubs for external and common global variables.
|
|
MachineModuleInfoELF::SymbolListTy Stubs = MMIELF.GetGVStubList();
|
|
if (!Stubs.empty()) {
|
|
OutStreamer.SwitchSection(TLOFELF.getDataRelSection());
|
|
const DataLayout *TD = TM.getDataLayout();
|
|
|
|
for (unsigned i = 0, e = Stubs.size(); i != e; ++i) {
|
|
OutStreamer.EmitLabel(Stubs[i].first);
|
|
OutStreamer.EmitSymbolValue(Stubs[i].second.getPointer(),
|
|
TD->getPointerSize(0));
|
|
}
|
|
Stubs.clear();
|
|
}
|
|
}
|
|
}
|
|
|
|
// Force static initialization.
|
|
extern "C" void LLVMInitializeSystemZAsmPrinter() {
|
|
RegisterAsmPrinter<SystemZAsmPrinter> X(TheSystemZTarget);
|
|
}
|