mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-23 03:02:36 +01:00
1924b30c0e
- TargetMachine implementation for M68k - ISel, ISched for M68k - Other lowering (e.g. FrameLowering) - AsmPrinter Authors: myhsu, m4yers, glaubitz Differential Revision: https://reviews.llvm.org/D88391
171 lines
5.2 KiB
C++
171 lines
5.2 KiB
C++
//===-- M68kMCInstLower.cpp - M68k MachineInstr to MCInst ---*- C++ -*-===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
///
|
|
/// \file
|
|
/// This file contains code to lower M68k MachineInstrs to their
|
|
/// corresponding MCInst records.
|
|
///
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "M68kMCInstLower.h"
|
|
|
|
#include "M68kAsmPrinter.h"
|
|
#include "M68kInstrInfo.h"
|
|
|
|
#include "MCTargetDesc/M68kBaseInfo.h"
|
|
|
|
#include "llvm/CodeGen/MachineFunction.h"
|
|
#include "llvm/CodeGen/MachineInstr.h"
|
|
#include "llvm/CodeGen/MachineOperand.h"
|
|
#include "llvm/IR/Mangler.h"
|
|
#include "llvm/MC/MCContext.h"
|
|
#include "llvm/MC/MCExpr.h"
|
|
#include "llvm/MC/MCInst.h"
|
|
|
|
using namespace llvm;
|
|
|
|
#define DEBUG_TYPE "m68k-mc-inst-lower"
|
|
|
|
M68kMCInstLower::M68kMCInstLower(MachineFunction &MF, M68kAsmPrinter &AP)
|
|
: Ctx(MF.getContext()), MF(MF), TM(MF.getTarget()), MAI(*TM.getMCAsmInfo()),
|
|
AsmPrinter(AP) {}
|
|
|
|
MCSymbol *
|
|
M68kMCInstLower::GetSymbolFromOperand(const MachineOperand &MO) const {
|
|
assert((MO.isGlobal() || MO.isSymbol() || MO.isMBB()) &&
|
|
"Isn't a symbol reference");
|
|
|
|
const auto &TT = TM.getTargetTriple();
|
|
if (MO.isGlobal() && TT.isOSBinFormatELF())
|
|
return AsmPrinter.getSymbolPreferLocal(*MO.getGlobal());
|
|
|
|
const DataLayout &DL = MF.getDataLayout();
|
|
|
|
MCSymbol *Sym = nullptr;
|
|
SmallString<128> Name;
|
|
StringRef Suffix;
|
|
|
|
if (!Suffix.empty())
|
|
Name += DL.getPrivateGlobalPrefix();
|
|
|
|
if (MO.isGlobal()) {
|
|
const GlobalValue *GV = MO.getGlobal();
|
|
AsmPrinter.getNameWithPrefix(Name, GV);
|
|
} else if (MO.isSymbol()) {
|
|
Mangler::getNameWithPrefix(Name, MO.getSymbolName(), DL);
|
|
} else if (MO.isMBB()) {
|
|
assert(Suffix.empty());
|
|
Sym = MO.getMBB()->getSymbol();
|
|
}
|
|
|
|
Name += Suffix;
|
|
if (!Sym)
|
|
Sym = Ctx.getOrCreateSymbol(Name);
|
|
|
|
return Sym;
|
|
}
|
|
|
|
MCOperand M68kMCInstLower::LowerSymbolOperand(const MachineOperand &MO,
|
|
MCSymbol *Sym) const {
|
|
// FIXME We would like an efficient form for this, so we don't have to do a
|
|
// lot of extra uniquing. This fixme is originally from X86
|
|
const MCExpr *Expr = nullptr;
|
|
MCSymbolRefExpr::VariantKind RefKind = MCSymbolRefExpr::VK_None;
|
|
|
|
switch (MO.getTargetFlags()) {
|
|
default:
|
|
llvm_unreachable("Unknown target flag on GV operand");
|
|
case M68kII::MO_NO_FLAG:
|
|
case M68kII::MO_ABSOLUTE_ADDRESS:
|
|
case M68kII::MO_PC_RELATIVE_ADDRESS:
|
|
break;
|
|
case M68kII::MO_GOTPCREL:
|
|
RefKind = MCSymbolRefExpr::VK_GOTPCREL;
|
|
break;
|
|
case M68kII::MO_GOT:
|
|
RefKind = MCSymbolRefExpr::VK_GOT;
|
|
break;
|
|
case M68kII::MO_GOTOFF:
|
|
RefKind = MCSymbolRefExpr::VK_GOTOFF;
|
|
break;
|
|
case M68kII::MO_PLT:
|
|
RefKind = MCSymbolRefExpr::VK_PLT;
|
|
break;
|
|
}
|
|
|
|
if (!Expr) {
|
|
Expr = MCSymbolRefExpr::create(Sym, RefKind, Ctx);
|
|
}
|
|
|
|
if (!MO.isJTI() && !MO.isMBB() && MO.getOffset()) {
|
|
Expr = MCBinaryExpr::createAdd(
|
|
Expr, MCConstantExpr::create(MO.getOffset(), Ctx), Ctx);
|
|
}
|
|
|
|
return MCOperand::createExpr(Expr);
|
|
}
|
|
|
|
Optional<MCOperand>
|
|
M68kMCInstLower::LowerOperand(const MachineInstr *MI,
|
|
const MachineOperand &MO) const {
|
|
switch (MO.getType()) {
|
|
default:
|
|
llvm_unreachable("unknown operand type");
|
|
case MachineOperand::MO_Register:
|
|
// Ignore all implicit register operands.
|
|
if (MO.isImplicit())
|
|
return None;
|
|
return MCOperand::createReg(MO.getReg());
|
|
case MachineOperand::MO_Immediate:
|
|
return MCOperand::createImm(MO.getImm());
|
|
case MachineOperand::MO_MachineBasicBlock:
|
|
case MachineOperand::MO_GlobalAddress:
|
|
case MachineOperand::MO_ExternalSymbol:
|
|
return LowerSymbolOperand(MO, GetSymbolFromOperand(MO));
|
|
case MachineOperand::MO_MCSymbol:
|
|
return LowerSymbolOperand(MO, MO.getMCSymbol());
|
|
case MachineOperand::MO_JumpTableIndex:
|
|
return LowerSymbolOperand(MO, AsmPrinter.GetJTISymbol(MO.getIndex()));
|
|
case MachineOperand::MO_ConstantPoolIndex:
|
|
return LowerSymbolOperand(MO, AsmPrinter.GetCPISymbol(MO.getIndex()));
|
|
case MachineOperand::MO_BlockAddress:
|
|
return LowerSymbolOperand(
|
|
MO, AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress()));
|
|
case MachineOperand::MO_RegisterMask:
|
|
// Ignore call clobbers.
|
|
return None;
|
|
}
|
|
}
|
|
|
|
void M68kMCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
|
|
unsigned Opcode = MI->getOpcode();
|
|
OutMI.setOpcode(Opcode);
|
|
|
|
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
|
|
const MachineOperand &MO = MI->getOperand(i);
|
|
Optional<MCOperand> MCOp = LowerOperand(MI, MO);
|
|
|
|
if (MCOp.hasValue() && MCOp.getValue().isValid())
|
|
OutMI.addOperand(MCOp.getValue());
|
|
}
|
|
|
|
// TAILJMPj, TAILJMPq - Lower to the correct jump instructions.
|
|
if (Opcode == M68k::TAILJMPj || Opcode == M68k::TAILJMPq) {
|
|
assert(OutMI.getNumOperands() == 1 && "Unexpected number of operands");
|
|
switch (Opcode) {
|
|
case M68k::TAILJMPj:
|
|
Opcode = M68k::JMP32j;
|
|
break;
|
|
case M68k::TAILJMPq:
|
|
Opcode = M68k::BRA8;
|
|
break;
|
|
}
|
|
OutMI.setOpcode(Opcode);
|
|
}
|
|
}
|