1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-21 03:53:04 +02:00
llvm-mirror/lib/Target/X86/X86RegisterBankInfo.cpp
Igor Breger d8d28772c9 [GlobalISel][X86] Support float/double and vector types.
Summary: [GlobalISel][X86] Add support for f32/f64 and vector types in RegisterBank and InstructionSelector.

Reviewers: delena, zvi

Reviewed By: zvi

Subscribers: dberris, rovka, llvm-commits, kristof.beyls

Differential Revision: https://reviews.llvm.org/D30533

llvm-svn: 296856
2017-03-03 08:06:46 +00:00

161 lines
4.7 KiB
C++

//===- X86RegisterBankInfo.cpp -----------------------------------*- C++ -*-==//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
/// \file
/// This file implements the targeting of the RegisterBankInfo class for X86.
/// \todo This should be generated by TableGen.
//===----------------------------------------------------------------------===//
#include "X86RegisterBankInfo.h"
#include "X86InstrInfo.h"
#include "llvm/CodeGen/GlobalISel/RegisterBank.h"
#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Target/TargetRegisterInfo.h"
#define GET_TARGET_REGBANK_IMPL
#include "X86GenRegisterBank.inc"
// This file will be TableGen'ed at some point.
#include "X86GenRegisterBankInfo.def"
using namespace llvm;
#ifndef LLVM_BUILD_GLOBAL_ISEL
#error "You shouldn't build this"
#endif
X86RegisterBankInfo::X86RegisterBankInfo(const TargetRegisterInfo &TRI)
: X86GenRegisterBankInfo() {
// validate RegBank initialization.
const RegisterBank &RBGPR = getRegBank(X86::GPRRegBankID);
(void)RBGPR;
assert(&X86::GPRRegBank == &RBGPR && "Incorrect RegBanks inizalization.");
// The GPR register bank is fully defined by all the registers in
// GR64 + its subclasses.
assert(RBGPR.covers(*TRI.getRegClass(X86::GR64RegClassID)) &&
"Subclass not added?");
assert(RBGPR.getSize() == 64 && "GPRs should hold up to 64-bit");
}
const RegisterBank &X86RegisterBankInfo::getRegBankFromRegClass(
const TargetRegisterClass &RC) const {
if (X86::GR8RegClass.hasSubClassEq(&RC) ||
X86::GR16RegClass.hasSubClassEq(&RC) ||
X86::GR32RegClass.hasSubClassEq(&RC) ||
X86::GR64RegClass.hasSubClassEq(&RC))
return getRegBank(X86::GPRRegBankID);
if (X86::FR32XRegClass.hasSubClassEq(&RC) ||
X86::FR64XRegClass.hasSubClassEq(&RC) ||
X86::VR128XRegClass.hasSubClassEq(&RC) ||
X86::VR256XRegClass.hasSubClassEq(&RC) ||
X86::VR512RegClass.hasSubClassEq(&RC))
return getRegBank(X86::VECRRegBankID);
llvm_unreachable("Unsupported register kind yet.");
}
RegisterBankInfo::InstructionMapping
X86RegisterBankInfo::getOperandsMapping(const MachineInstr &MI, bool isFP) {
const MachineFunction &MF = *MI.getParent()->getParent();
const MachineRegisterInfo &MRI = MF.getRegInfo();
unsigned NumOperands = MI.getNumOperands();
LLT Ty = MRI.getType(MI.getOperand(0).getReg());
if (NumOperands != 3 ||
(Ty != MRI.getType(MI.getOperand(1).getReg())) ||
(Ty != MRI.getType(MI.getOperand(2).getReg())))
llvm_unreachable("Unsupported operand maping yet.");
ValueMappingIdx ValMapIdx = VMI_None;
if (Ty.isScalar()) {
if (!isFP) {
switch (Ty.getSizeInBits()) {
case 8:
ValMapIdx = VMI_3OpsGpr8Idx;
break;
case 16:
ValMapIdx = VMI_3OpsGpr16Idx;
break;
case 32:
ValMapIdx = VMI_3OpsGpr32Idx;
break;
case 64:
ValMapIdx = VMI_3OpsGpr64Idx;
break;
default:
llvm_unreachable("Unsupported register size.");
}
} else {
switch (Ty.getSizeInBits()) {
case 32:
ValMapIdx = VMI_3OpsFp32Idx;
break;
case 64:
ValMapIdx = VMI_3OpsFp64Idx;
break;
default:
llvm_unreachable("Unsupported register size.");
}
}
} else {
switch (Ty.getSizeInBits()) {
case 128:
ValMapIdx = VMI_3OpsVec128Idx;
break;
case 256:
ValMapIdx = VMI_3OpsVec256Idx;
break;
case 512:
ValMapIdx = VMI_3OpsVec512Idx;
break;
default:
llvm_unreachable("Unsupported register size.");
}
}
return InstructionMapping{DefaultMappingID, 1, &ValMappings[ValMapIdx],
NumOperands};
}
RegisterBankInfo::InstructionMapping
X86RegisterBankInfo::getInstrMapping(const MachineInstr &MI) const {
auto Opc = MI.getOpcode();
// Try the default logic for non-generic instructions that are either copies
// or already have some operands assigned to banks.
if (!isPreISelGenericOpcode(Opc)) {
InstructionMapping Mapping = getInstrMappingImpl(MI);
if (Mapping.isValid())
return Mapping;
}
switch (Opc) {
case TargetOpcode::G_ADD:
case TargetOpcode::G_SUB:
return getOperandsMapping(MI, false);
break;
case TargetOpcode::G_FADD:
case TargetOpcode::G_FSUB:
case TargetOpcode::G_FMUL:
case TargetOpcode::G_FDIV:
return getOperandsMapping(MI, true);
break;
default:
return InstructionMapping{};
}
return InstructionMapping{};
}