mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-23 02:29:18 +00:00
This (r232027) has caused PR22883; so it seems those bits might be used by something else after all. Reverting until we can figure out what else to do. Original commit message: The operand flag word for ISD::INLINEASM nodes now contains a 15-bit memory constraint ID when the operand kind is Kind_Mem. This constraint ID is a numeric equivalent to the constraint code string and is converted with a target specific hook in TargetLowering. This patch maps all memory constraints to InlineAsm::Constraint_m so there is no functional change at this point. It just proves that using these previously unused bits in the encoding of the flag word doesn't break anything. The next patch will make each target preserve the current mapping of everything to Constraint_m for itself while changing the target independent implementation of the hook to return Constraint_Unknown appropriately. Each target will then be adapted in separate patches to use appropriate Constraint_* values. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@232093 91177308-0d34-0410-b5e6-96231b3b80d8
239 lines
7.4 KiB
C++
239 lines
7.4 KiB
C++
//===-- MipsISelDAGToDAG.cpp - A Dag to Dag Inst Selector for Mips --------===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// This file defines an instruction selector for the MIPS target.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "MipsISelDAGToDAG.h"
|
|
#include "MCTargetDesc/MipsBaseInfo.h"
|
|
#include "Mips.h"
|
|
#include "Mips16ISelDAGToDAG.h"
|
|
#include "MipsMachineFunction.h"
|
|
#include "MipsRegisterInfo.h"
|
|
#include "MipsSEISelDAGToDAG.h"
|
|
#include "llvm/CodeGen/MachineConstantPool.h"
|
|
#include "llvm/CodeGen/MachineFrameInfo.h"
|
|
#include "llvm/CodeGen/MachineFunction.h"
|
|
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
|
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
|
#include "llvm/CodeGen/SelectionDAGNodes.h"
|
|
#include "llvm/IR/CFG.h"
|
|
#include "llvm/IR/GlobalValue.h"
|
|
#include "llvm/IR/Instructions.h"
|
|
#include "llvm/IR/Intrinsics.h"
|
|
#include "llvm/IR/Type.h"
|
|
#include "llvm/Support/Debug.h"
|
|
#include "llvm/Support/ErrorHandling.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
#include "llvm/Target/TargetMachine.h"
|
|
using namespace llvm;
|
|
|
|
#define DEBUG_TYPE "mips-isel"
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// Instruction Selector Implementation
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
// MipsDAGToDAGISel - MIPS specific code to select MIPS machine
|
|
// instructions for SelectionDAG operations.
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
bool MipsDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) {
|
|
Subtarget = &static_cast<const MipsSubtarget &>(MF.getSubtarget());
|
|
bool Ret = SelectionDAGISel::runOnMachineFunction(MF);
|
|
|
|
processFunctionAfterISel(MF);
|
|
|
|
return Ret;
|
|
}
|
|
|
|
/// getGlobalBaseReg - Output the instructions required to put the
|
|
/// GOT address into a register.
|
|
SDNode *MipsDAGToDAGISel::getGlobalBaseReg() {
|
|
unsigned GlobalBaseReg = MF->getInfo<MipsFunctionInfo>()->getGlobalBaseReg();
|
|
return CurDAG->getRegister(GlobalBaseReg,
|
|
getTargetLowering()->getPointerTy()).getNode();
|
|
}
|
|
|
|
/// ComplexPattern used on MipsInstrInfo
|
|
/// Used on Mips Load/Store instructions
|
|
bool MipsDAGToDAGISel::selectAddrRegImm(SDValue Addr, SDValue &Base,
|
|
SDValue &Offset) const {
|
|
llvm_unreachable("Unimplemented function.");
|
|
return false;
|
|
}
|
|
|
|
bool MipsDAGToDAGISel::selectAddrRegReg(SDValue Addr, SDValue &Base,
|
|
SDValue &Offset) const {
|
|
llvm_unreachable("Unimplemented function.");
|
|
return false;
|
|
}
|
|
|
|
bool MipsDAGToDAGISel::selectAddrDefault(SDValue Addr, SDValue &Base,
|
|
SDValue &Offset) const {
|
|
llvm_unreachable("Unimplemented function.");
|
|
return false;
|
|
}
|
|
|
|
bool MipsDAGToDAGISel::selectIntAddr(SDValue Addr, SDValue &Base,
|
|
SDValue &Offset) const {
|
|
llvm_unreachable("Unimplemented function.");
|
|
return false;
|
|
}
|
|
|
|
bool MipsDAGToDAGISel::selectIntAddrMM(SDValue Addr, SDValue &Base,
|
|
SDValue &Offset) const {
|
|
llvm_unreachable("Unimplemented function.");
|
|
return false;
|
|
}
|
|
|
|
bool MipsDAGToDAGISel::selectIntAddrLSL2MM(SDValue Addr, SDValue &Base,
|
|
SDValue &Offset) const {
|
|
llvm_unreachable("Unimplemented function.");
|
|
return false;
|
|
}
|
|
|
|
bool MipsDAGToDAGISel::selectIntAddrMSA(SDValue Addr, SDValue &Base,
|
|
SDValue &Offset) const {
|
|
llvm_unreachable("Unimplemented function.");
|
|
return false;
|
|
}
|
|
|
|
bool MipsDAGToDAGISel::selectAddr16(SDNode *Parent, SDValue N, SDValue &Base,
|
|
SDValue &Offset, SDValue &Alias) {
|
|
llvm_unreachable("Unimplemented function.");
|
|
return false;
|
|
}
|
|
|
|
bool MipsDAGToDAGISel::selectVSplat(SDNode *N, APInt &Imm) const {
|
|
llvm_unreachable("Unimplemented function.");
|
|
return false;
|
|
}
|
|
|
|
bool MipsDAGToDAGISel::selectVSplatUimm1(SDValue N, SDValue &Imm) const {
|
|
llvm_unreachable("Unimplemented function.");
|
|
return false;
|
|
}
|
|
|
|
bool MipsDAGToDAGISel::selectVSplatUimm2(SDValue N, SDValue &Imm) const {
|
|
llvm_unreachable("Unimplemented function.");
|
|
return false;
|
|
}
|
|
|
|
bool MipsDAGToDAGISel::selectVSplatUimm3(SDValue N, SDValue &Imm) const {
|
|
llvm_unreachable("Unimplemented function.");
|
|
return false;
|
|
}
|
|
|
|
bool MipsDAGToDAGISel::selectVSplatUimm4(SDValue N, SDValue &Imm) const {
|
|
llvm_unreachable("Unimplemented function.");
|
|
return false;
|
|
}
|
|
|
|
bool MipsDAGToDAGISel::selectVSplatUimm5(SDValue N, SDValue &Imm) const {
|
|
llvm_unreachable("Unimplemented function.");
|
|
return false;
|
|
}
|
|
|
|
bool MipsDAGToDAGISel::selectVSplatUimm6(SDValue N, SDValue &Imm) const {
|
|
llvm_unreachable("Unimplemented function.");
|
|
return false;
|
|
}
|
|
|
|
bool MipsDAGToDAGISel::selectVSplatUimm8(SDValue N, SDValue &Imm) const {
|
|
llvm_unreachable("Unimplemented function.");
|
|
return false;
|
|
}
|
|
|
|
bool MipsDAGToDAGISel::selectVSplatSimm5(SDValue N, SDValue &Imm) const {
|
|
llvm_unreachable("Unimplemented function.");
|
|
return false;
|
|
}
|
|
|
|
bool MipsDAGToDAGISel::selectVSplatUimmPow2(SDValue N, SDValue &Imm) const {
|
|
llvm_unreachable("Unimplemented function.");
|
|
return false;
|
|
}
|
|
|
|
bool MipsDAGToDAGISel::selectVSplatUimmInvPow2(SDValue N, SDValue &Imm) const {
|
|
llvm_unreachable("Unimplemented function.");
|
|
return false;
|
|
}
|
|
|
|
bool MipsDAGToDAGISel::selectVSplatMaskL(SDValue N, SDValue &Imm) const {
|
|
llvm_unreachable("Unimplemented function.");
|
|
return false;
|
|
}
|
|
|
|
bool MipsDAGToDAGISel::selectVSplatMaskR(SDValue N, SDValue &Imm) const {
|
|
llvm_unreachable("Unimplemented function.");
|
|
return false;
|
|
}
|
|
|
|
/// Select instructions not customized! Used for
|
|
/// expanded, promoted and normal instructions
|
|
SDNode* MipsDAGToDAGISel::Select(SDNode *Node) {
|
|
unsigned Opcode = Node->getOpcode();
|
|
|
|
// Dump information about the Node being selected
|
|
DEBUG(errs() << "Selecting: "; Node->dump(CurDAG); errs() << "\n");
|
|
|
|
// If we have a custom node, we already have selected!
|
|
if (Node->isMachineOpcode()) {
|
|
DEBUG(errs() << "== "; Node->dump(CurDAG); errs() << "\n");
|
|
Node->setNodeId(-1);
|
|
return nullptr;
|
|
}
|
|
|
|
// See if subclasses can handle this node.
|
|
std::pair<bool, SDNode*> Ret = selectNode(Node);
|
|
|
|
if (Ret.first)
|
|
return Ret.second;
|
|
|
|
switch(Opcode) {
|
|
default: break;
|
|
|
|
// Get target GOT address.
|
|
case ISD::GLOBAL_OFFSET_TABLE:
|
|
return getGlobalBaseReg();
|
|
|
|
#ifndef NDEBUG
|
|
case ISD::LOAD:
|
|
case ISD::STORE:
|
|
assert((Subtarget->systemSupportsUnalignedAccess() ||
|
|
cast<MemSDNode>(Node)->getMemoryVT().getSizeInBits() / 8 <=
|
|
cast<MemSDNode>(Node)->getAlignment()) &&
|
|
"Unexpected unaligned loads/stores.");
|
|
break;
|
|
#endif
|
|
}
|
|
|
|
// Select the default instruction
|
|
SDNode *ResNode = SelectCode(Node);
|
|
|
|
DEBUG(errs() << "=> ");
|
|
if (ResNode == nullptr || ResNode == Node)
|
|
DEBUG(Node->dump(CurDAG));
|
|
else
|
|
DEBUG(ResNode->dump(CurDAG));
|
|
DEBUG(errs() << "\n");
|
|
return ResNode;
|
|
}
|
|
|
|
bool MipsDAGToDAGISel::
|
|
SelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode,
|
|
std::vector<SDValue> &OutOps) {
|
|
assert(ConstraintCode == 'm' && "unexpected asm memory constraint");
|
|
OutOps.push_back(Op);
|
|
return false;
|
|
}
|