LLVM  10.0.0svn
MipsLegalizerInfo.cpp
Go to the documentation of this file.
1 //===- MipsLegalizerInfo.cpp ------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 /// This file implements the targeting of the Machinelegalizer class for Mips.
10 /// \todo This should be generated by TableGen.
11 //===----------------------------------------------------------------------===//
12 
13 #include "MipsLegalizerInfo.h"
14 #include "MipsTargetMachine.h"
16 
17 using namespace llvm;
18 
20  using namespace TargetOpcode;
21 
22  const LLT s1 = LLT::scalar(1);
23  const LLT s32 = LLT::scalar(32);
24  const LLT s64 = LLT::scalar(64);
25  const LLT p0 = LLT::pointer(0, 32);
26 
27  getActionDefinitionsBuilder({G_ADD, G_SUB, G_MUL})
28  .legalFor({s32})
29  .clampScalar(0, s32, s32);
30 
31  getActionDefinitionsBuilder({G_UADDO, G_UADDE, G_USUBO, G_USUBE, G_UMULO})
32  .lowerFor({{s32, s1}});
33 
35  .legalFor({s32})
36  .maxScalar(0, s32);
37 
38  getActionDefinitionsBuilder({G_LOAD, G_STORE})
39  .legalForTypesWithMemDesc({{s32, p0, 8, 8},
40  {s32, p0, 16, 8},
41  {s32, p0, 32, 8},
42  {s64, p0, 64, 8},
43  {p0, p0, 32, 8}})
44  .minScalar(0, s32);
45 
46  getActionDefinitionsBuilder(G_IMPLICIT_DEF)
47  .legalFor({s32, s64});
48 
49  getActionDefinitionsBuilder(G_UNMERGE_VALUES)
50  .legalFor({{s32, s64}});
51 
52  getActionDefinitionsBuilder(G_MERGE_VALUES)
53  .legalFor({{s64, s32}});
54 
55  getActionDefinitionsBuilder({G_ZEXTLOAD, G_SEXTLOAD})
56  .legalForTypesWithMemDesc({{s32, p0, 8, 8},
57  {s32, p0, 16, 8}})
58  .clampScalar(0, s32, s32);
59 
60  getActionDefinitionsBuilder({G_ZEXT, G_SEXT})
61  .legalIf([](const LegalityQuery &Query) { return false; })
62  .maxScalar(0, s32);
63 
65  .legalIf([](const LegalityQuery &Query) { return false; })
66  .maxScalar(1, s32);
67 
69  .legalForCartesianProduct({p0, s32, s64}, {s32})
70  .minScalar(0, s32)
71  .minScalar(1, s32);
72 
74  .legalFor({s32})
75  .minScalar(0, s32);
76 
78  .legalFor({{p0, s32}});
79 
80  getActionDefinitionsBuilder(G_BRINDIRECT)
81  .legalFor({p0});
82 
84  .legalFor({p0, s32, s64})
85  .minScalar(0, s32);
86 
87  getActionDefinitionsBuilder({G_AND, G_OR, G_XOR})
88  .legalFor({s32})
89  .clampScalar(0, s32, s32);
90 
91  getActionDefinitionsBuilder({G_SDIV, G_SREM, G_UREM, G_UDIV})
92  .legalFor({s32})
93  .minScalar(0, s32)
94  .libcallFor({s64});
95 
96  getActionDefinitionsBuilder({G_SHL, G_ASHR, G_LSHR})
97  .legalFor({{s32, s32}})
98  .clampScalar(1, s32, s32)
99  .clampScalar(0, s32, s32);
100 
102  .legalForCartesianProduct({s32}, {s32, p0})
103  .clampScalar(1, s32, s32)
104  .minScalar(0, s32);
105 
106  getActionDefinitionsBuilder(G_CONSTANT)
107  .legalFor({s32})
108  .clampScalar(0, s32, s32);
109 
110  getActionDefinitionsBuilder({G_GEP, G_INTTOPTR})
111  .legalFor({{p0, s32}});
112 
113  getActionDefinitionsBuilder(G_PTRTOINT)
114  .legalFor({{s32, p0}});
115 
116  getActionDefinitionsBuilder(G_FRAME_INDEX)
117  .legalFor({p0});
118 
119  getActionDefinitionsBuilder({G_GLOBAL_VALUE, G_JUMP_TABLE})
120  .legalFor({p0});
121 
122  getActionDefinitionsBuilder(G_DYN_STACKALLOC)
123  .lowerFor({{p0, s32}});
124 
125  // FP instructions
126  getActionDefinitionsBuilder(G_FCONSTANT)
127  .legalFor({s32, s64});
128 
129  getActionDefinitionsBuilder({G_FADD, G_FSUB, G_FMUL, G_FDIV, G_FABS, G_FSQRT})
130  .legalFor({s32, s64});
131 
133  .legalFor({{s32, s32}, {s32, s64}})
134  .minScalar(0, s32);
135 
136  getActionDefinitionsBuilder({G_FCEIL, G_FFLOOR})
137  .libcallFor({s32, s64});
138 
140  .legalFor({{s64, s32}});
141 
142  getActionDefinitionsBuilder(G_FPTRUNC)
143  .legalFor({{s32, s64}});
144 
145  // FP to int conversion instructions
147  .legalForCartesianProduct({s32}, {s64, s32})
148  .libcallForCartesianProduct({s64}, {s64, s32})
149  .minScalar(0, s32);
150 
152  .libcallForCartesianProduct({s64}, {s64, s32})
153  .lowerForCartesianProduct({s32}, {s64, s32})
154  .minScalar(0, s32);
155 
156  // Int to FP conversion instructions
158  .legalForCartesianProduct({s64, s32}, {s32})
159  .libcallForCartesianProduct({s64, s32}, {s64})
160  .minScalar(1, s32);
161 
163  .libcallForCartesianProduct({s64, s32}, {s64})
164  .customForCartesianProduct({s64, s32}, {s32})
165  .minScalar(1, s32);
166 
167  getActionDefinitionsBuilder(G_SEXT_INREG).lower();
168 
169  computeTables();
170  verify(*ST.getInstrInfo());
171 }
172 
175  MachineIRBuilder &MIRBuilder,
176  GISelChangeObserver &Observer) const {
177 
178  using namespace TargetOpcode;
179 
180  MIRBuilder.setInstr(MI);
181  const MipsSubtarget &STI =
182  static_cast<const MipsSubtarget &>(MIRBuilder.getMF().getSubtarget());
183  const LLT s32 = LLT::scalar(32);
184  const LLT s64 = LLT::scalar(64);
185 
186  switch (MI.getOpcode()) {
187  case G_UITOFP: {
188  Register Dst = MI.getOperand(0).getReg();
189  Register Src = MI.getOperand(1).getReg();
190  LLT DstTy = MRI.getType(Dst);
191  LLT SrcTy = MRI.getType(Src);
192 
193  if (SrcTy != s32)
194  return false;
195  if (DstTy != s32 && DstTy != s64)
196  return false;
197 
198  // Let 0xABCDEFGH be given unsigned in MI.getOperand(1). First let's convert
199  // unsigned to double. Mantissa has 52 bits so we use following trick:
200  // First make floating point bit mask 0x43300000ABCDEFGH.
201  // Mask represents 2^52 * 0x1.00000ABCDEFGH i.e. 0x100000ABCDEFGH.0 .
202  // Next, subtract 2^52 * 0x1.0000000000000 i.e. 0x10000000000000.0 from it.
203  // Done. Trunc double to float if needed.
204 
206  STI.isFP64bit() ? Mips::BuildPairF64_64 : Mips::BuildPairF64, {s64},
207  {Src, MIRBuilder.buildConstant(s32, UINT32_C(0x43300000))});
208  Bitcast.constrainAllUses(MIRBuilder.getTII(), *STI.getRegisterInfo(),
209  *STI.getRegBankInfo());
210 
211  MachineInstrBuilder TwoP52FP = MIRBuilder.buildFConstant(
212  s64, BitsToDouble(UINT64_C(0x4330000000000000)));
213 
214  if (DstTy == s64)
215  MIRBuilder.buildFSub(Dst, Bitcast, TwoP52FP);
216  else {
217  MachineInstrBuilder ResF64 = MIRBuilder.buildFSub(s64, Bitcast, TwoP52FP);
218  MIRBuilder.buildFPTrunc(Dst, ResF64);
219  }
220 
221  MI.eraseFromParent();
222  break;
223  }
224  default:
225  return false;
226  }
227 
228  return true;
229 }
230 
233  MachineIRBuilder &MIRBuilder) const {
234  const MipsSubtarget &ST =
235  static_cast<const MipsSubtarget &>(MI.getMF()->getSubtarget());
236  const MipsInstrInfo &TII = *ST.getInstrInfo();
237  const MipsRegisterInfo &TRI = *ST.getRegisterInfo();
238  const RegisterBankInfo &RBI = *ST.getRegBankInfo();
239  MIRBuilder.setInstr(MI);
240 
241  switch (MI.getIntrinsicID()) {
242  case Intrinsic::memcpy:
243  case Intrinsic::memset:
244  case Intrinsic::memmove:
245  if (createMemLibcall(MIRBuilder, MRI, MI) ==
247  return false;
248  MI.eraseFromParent();
249  return true;
250  case Intrinsic::trap: {
251  MachineInstr *Trap = MIRBuilder.buildInstr(Mips::TRAP);
252  MI.eraseFromParent();
253  return constrainSelectedInstRegOperands(*Trap, TII, TRI, RBI);
254  }
255  default:
256  break;
257  }
258  return true;
259 }
const RegisterBankInfo * getRegBankInfo() const override
virtual MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
static LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
This class represents lattice values for constants.
Definition: AllocatorList.h:23
MipsLegalizerInfo(const MipsSubtarget &ST)
The LegalityQuery object bundles together all the information that&#39;s needed to decide whether a given...
const MipsInstrInfo * getInstrInfo() const override
This file declares the targeting of the Machinelegalizer class for Mips.
LLT getType(unsigned Reg) const
Get the low-level type of Reg or LLT{} if Reg is not a generic (target independent) virtual register...
unsigned const TargetRegisterInfo * TRI
bool legalizeIntrinsic(MachineInstr &MI, MachineRegisterInfo &MRI, MachineIRBuilder &MIRBuilder) const override
Return true if MI is either legal or has been legalized and false if not legal.
LegalizeRuleSet & libcallForCartesianProduct(std::initializer_list< LLT > Types)
LegalizeRuleSet & legalForCartesianProduct(std::initializer_list< LLT > Types)
The instruction is legal when type indexes 0 and 1 are both in the given list.
Holds all the information related to register banks.
const HexagonInstrInfo * TII
void eraseFromParent()
Unlink &#39;this&#39; from the containing basic block and delete it.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:411
void verify(const MCInstrInfo &MII) const
Perform simple self-diagnostic and assert if there is anything obviously wrong with the actions set u...
MachineInstrBuilder buildFSub(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1)
Build and insert Res = G_FSUB Op0, Op1.
void computeTables()
Compute any ancillary tables needed to quickly decide how an operation should be handled.
MachineFunction & getMF()
Getter for the function we currently build.
static LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
LegalizeRuleSet & legalIf(LegalityPredicate Predicate)
The instruction is legal if predicate is true.
Abstract class that contains various methods for clients to notify about changes. ...
MachineInstrBuilder buildFPTrunc(const DstOp &Res, const SrcOp &Op)
Build and insert Res = G_FPTRUNC Op.
unsigned const MachineRegisterInfo * MRI
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineInstrBuilder buildInstr(unsigned Opcode)
Build and insert <empty> = Opcode <empty>.
LegalizeRuleSet & lowerFor(std::initializer_list< LLT > Types)
The instruction is lowered when type index 0 is any type in the given list.
LegalizeRuleSet & libcallFor(std::initializer_list< LLT > Types)
Helper class to build MachineInstr.
void setInstr(MachineInstr &MI)
Set the insertion point to before MI.
TRAP - Trapping instruction.
Definition: ISDOpcodes.h:798
LegalizerHelper::LegalizeResult createMemLibcall(MachineIRBuilder &MIRBuilder, MachineRegisterInfo &MRI, MachineInstr &MI)
Create a libcall to memcpy et al.
LegalizeRuleSet & clampScalar(unsigned TypeIdx, const LLT &MinTy, const LLT &MaxTy)
Limit the range of scalar sizes to MinTy and MaxTy.
Some kind of error has occurred and we could not legalize this instruction.
LegalizeRuleSet & minScalar(unsigned TypeIdx, const LLT &Ty)
Ensure the scalar is at least as wide as Ty.
LegalizeRuleSet & getActionDefinitionsBuilder(unsigned Opcode)
Get the action definition builder for the given opcode.
virtual MachineInstrBuilder buildFConstant(const DstOp &Res, const ConstantFP &Val)
Build and insert Res = G_FCONSTANT Val.
const MipsRegisterInfo * getRegisterInfo() const override
const TargetInstrInfo & getTII()
bool constrainSelectedInstRegOperands(MachineInstr &I, const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI)
Mutate the newly-selected instruction I to constrain its (possibly generic) virtual register operands...
Definition: Utils.cpp:111
double BitsToDouble(uint64_t Bits)
This function takes a 64-bit integer and returns the bit equivalent double.
Definition: MathExtras.h:577
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
LegalizeRuleSet & legalFor(std::initializer_list< LLT > Types)
The instruction is legal when type index 0 is any type in the given list.
Representation of each machine instruction.
Definition: MachineInstr.h:64
LegalizeRuleSet & lower()
The instruction is lowered.
bool legalizeCustom(MachineInstr &MI, MachineRegisterInfo &MRI, MachineIRBuilder &MIRBuilder, GISelChangeObserver &Observer) const override
unsigned getIntrinsicID() const
Returns the Intrinsic::ID for this instruction.
IRTranslator LLVM IR MI
Register getReg() const
getReg - Returns the register number.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:416
bool isFP64bit() const
bool constrainAllUses(const TargetInstrInfo &TII, const TargetRegisterInfo &TRI, const RegisterBankInfo &RBI) const
Wrapper class representing virtual and physical registers.
Definition: Register.h:19