29 : MachineEvaluator(tri, mri), MF(mf), MFI(*mf.getFrameInfo()),
TII(tii) {
47 unsigned InVirtReg, InPhysReg = 0;
61 if (Width == 0 || Width > 64)
63 InPhysReg = getNextPhysReg(InPhysReg, Width);
66 InVirtReg = getVirtRegFor(InPhysReg);
71 VRX.
insert(std::make_pair(InVirtReg, ExtType(ExtType::SExt, Width)));
73 VRX.
insert(std::make_pair(InVirtReg, ExtType(ExtType::ZExt, Width)));
80 return MachineEvaluator::mask(Reg, 0);
81 using namespace Hexagon;
83 unsigned ID = RC->getID();
86 case DoubleRegsRegClassID:
100 struct RegisterRefs :
public std::vector<BT::RegisterRef> {
101 typedef std::vector<BT::RegisterRef> Base;
106 return Base::operator[](n);
111 : Base(MI->getNumOperands()) {
112 for (
unsigned i = 0, n =
size(); i < n; ++i) {
125 unsigned NumDefs = 0;
140 return evaluateLoad(MI, Inputs, Outputs);
157 if (evaluateFormalCopy(MI, Inputs, Outputs))
174 RegisterRefs
Reg(MI);
176 using namespace Hexagon;
177 #define op(i) MI->getOperand(i)
178 #define rc(i) RegisterCell::ref(getCell(Reg[i],Inputs))
179 #define im(i) MI->getOperand(i).getImm()
192 auto cop = [
this,
Reg,
MI,Inputs] (
unsigned N, uint16_t W)
205 assert(RW <= RC.width());
206 return eXTR(RC, 0, RW);
211 uint16_t W = RC.
width();
213 return eXTR(RC, W-RW, W);
218 assert(
N*16+16 <= RC.width());
219 return eXTR(RC,
N*16,
N*16+16);
224 uint16_t
I = Odd, Ws = Rs.width();
225 assert(Ws == Rt.width());
247 case CONST32_Float_Real:
248 case CONST32_Int_Real:
249 case CONST64_Float_Real:
250 case CONST64_Int_Real:
251 return rr0(
eIMM(
im(1), W0), Outputs);
257 int FI =
op(1).getIndex();
258 int Off =
op(2).getImm();
263 return rr0(RC, Outputs);
271 return rr0(
rc(1), Outputs);
279 return rr0(RC, Outputs);
284 return rr0(
eINS(RC,
eXTR(
rc(1), 0, W0), 0), Outputs);
296 assert(W0 == 64 && W1 == 32);
299 return rr0(RC, Outputs);
303 return rr0(
eADD(
rc(1),
rc(2)), Outputs);
306 case S4_addi_asl_ri: {
308 return rr0(RC, Outputs);
310 case S4_addi_lsr_ri: {
312 return rr0(RC, Outputs);
316 return rr0(RC, Outputs);
318 case M4_mpyri_addi: {
321 return rr0(RC, Outputs);
323 case M4_mpyrr_addi: {
326 return rr0(RC, Outputs);
328 case M4_mpyri_addr_u2: {
331 return rr0(RC, Outputs);
333 case M4_mpyri_addr: {
336 return rr0(RC, Outputs);
338 case M4_mpyrr_addr: {
341 return rr0(RC, Outputs);
345 return rr0(RC, Outputs);
349 return rr0(RC, Outputs);
353 return rr0(RC, Outputs);
357 return rr0(RC, Outputs);
359 case S2_addasl_rrri: {
361 return rr0(RC, Outputs);
366 return rr0(
eADD(RPC,
eIMM(
im(2), W0)), Outputs);
370 return rr0(
eSUB(
rc(1),
rc(2)), Outputs);
373 case S4_subi_asl_ri: {
375 return rr0(RC, Outputs);
377 case S4_subi_lsr_ri: {
379 return rr0(RC, Outputs);
383 return rr0(RC, Outputs);
387 return rr0(RC, Outputs);
391 return rr0(
eSUB(
eIMM(0, W0),
rc(1)), Outputs);
395 return rr0(hi(M, W0), Outputs);
398 return rr0(
eMLS(
rc(1),
rc(2)), Outputs);
399 case M2_dpmpyss_acc_s0:
401 case M2_dpmpyss_nac_s0:
405 return rr0(lo(M, W0), Outputs);
410 return rr0(RC, Outputs);
415 return rr0(RC, Outputs);
420 return rr0(RC, Outputs);
424 return rr0(lo(M, 32), Outputs);
428 return rr0(lo(M, 32), Outputs);
432 return rr0(lo(M, 32), Outputs);
436 return rr0(hi(M, W0), Outputs);
439 return rr0(
eMLU(
rc(1),
rc(2)), Outputs);
440 case M2_dpmpyuu_acc_s0:
442 case M2_dpmpyuu_nac_s0:
452 return rr0(
eAND(
rc(1),
rc(2)), Outputs);
456 case S4_andi_asl_ri: {
458 return rr0(RC, Outputs);
460 case S4_andi_lsr_ri: {
462 return rr0(RC, Outputs);
476 return rr0(
eORL(
rc(1),
rc(2)), Outputs);
480 case S4_ori_asl_ri: {
482 return rr0(RC, Outputs);
484 case S4_ori_lsr_ri: {
486 return rr0(RC, Outputs);
495 return rr0(RC, Outputs);
499 return rr0(RC, Outputs);
507 return rr0(
eXOR(
rc(1),
rc(2)), Outputs);
518 return rr0(
eNOT(
rc(1)), Outputs);
522 return rr0(
eASL(
rc(1),
im(2)), Outputs);
524 return rr0(
eASL(
rc(1), 16), Outputs);
537 case S2_asl_i_r_xacc:
538 case S2_asl_i_p_xacc:
547 return rr0(
eASR(
rc(1),
im(2)), Outputs);
549 return rr0(
eASR(
rc(1), 16), Outputs);
562 case S2_asr_i_r_rnd: {
568 return rr0(
eXTR(RC, 0, W0), Outputs);
570 case S2_asr_i_r_rnd_goodsyntax: {
573 return rr0(
rc(1), Outputs);
577 return rr0(
eXTR(RC, 0, W0), Outputs);
581 case S2_asr_i_svw_trun:
587 return rr0(
eLSR(
rc(1),
im(2)), Outputs);
600 case S2_lsr_i_r_xacc:
601 case S2_lsr_i_p_xacc:
607 return rr0(RC, Outputs);
612 return rr0(RC, Outputs);
614 case S2_togglebit_i: {
620 return rr0(RC, Outputs);
629 .
fill(W1+(W1-BX), W0, Zero);
632 return rr0(RC, Outputs);
638 uint16_t Wd =
im(2), Of =
im(3);
641 return rr0(
eIMM(0, W0), Outputs);
648 if (Opc == S2_extractu || Opc == S2_extractup)
649 return rr0(
eZXT(RC, Wd), Outputs);
650 return rr0(
eSXT(RC, Wd), Outputs);
654 uint16_t Wd =
im(3), Of =
im(4);
655 assert(Wd < W0 && Of < W0);
660 return rr0(
rc(1), Outputs);
661 return rr0(
eINS(
rc(1),
eXTR(
rc(2), 0, Wd), Of), Outputs);
672 return rr0(cop(2, W0/2).cat(cop(1, W0/2)), Outputs);
676 case A2_combine_hh: {
680 unsigned LoH = !(Opc == A2_combine_ll || Opc == A2_combine_hl);
682 unsigned HiH = !(Opc == A2_combine_ll || Opc == A2_combine_lh);
686 return rr0(RC, Outputs);
695 return rr0(RC, Outputs);
699 return rr0(RC, Outputs);
703 return rr0(RC, Outputs);
707 return rr0(RC, Outputs);
711 return rr0(RC, Outputs);
716 assert(WR == 64 && WP == 8);
719 for (uint16_t i = 0; i < WP; ++i) {
722 RC.
fill(i*8, i*8+8, F);
724 return rr0(RC, Outputs);
736 if (PC0.
is(0) || PC0.
is(1))
738 R2.
meet(R3, Reg[0].Reg);
739 return rr0(R2, Outputs);
748 return rr0(
eSXT(
rc(1), 8), Outputs);
750 return rr0(
eSXT(
rc(1), 16), Outputs);
753 assert(W0 == 64 && W1 == 32);
755 return rr0(RC, Outputs);
758 return rr0(
eZXT(
rc(1), 8), Outputs);
760 return rr0(
eZXT(
rc(1), 16), Outputs);
767 return rr0(
eCLB(
rc(1), 0, 32), Outputs);
770 return rr0(
eCLB(
rc(1), 1, 32), Outputs);
776 if (TV.
is(0) || TV.
is(1))
777 return rr0(
eCLB(R1, TV, 32), Outputs);
782 return rr0(
eCTB(
rc(1), 0, 32), Outputs);
785 return rr0(
eCTB(
rc(1), 1, 32), Outputs);
792 bool Has0 =
false, All1 =
true;
793 for (uint16_t i = 0; i < 8; ++i) {
805 return rr0(RC, Outputs);
809 bool Has1 =
false, All0 =
true;
810 for (uint16_t i = 0; i < 8; ++i) {
822 return rr0(RC, Outputs);
825 return rr0(
eAND(
rc(1),
rc(2)), Outputs);
829 return rr0(
eNOT(
rc(1)), Outputs);
831 return rr0(
eORL(
rc(1),
rc(2)), Outputs);
835 return rr0(
eXOR(
rc(1),
rc(2)), Outputs);
863 if (V.
is(0) || V.
is(1)) {
865 bool TV = (Opc == S2_tstbit_i);
873 return MachineEvaluator::evaluate(MI, Inputs, Outputs);
884 bool &FallsThru)
const {
888 bool SimpleBranch =
false;
889 bool Negated =
false;
891 case Hexagon::J2_jumpf:
892 case Hexagon::J2_jumpfnew:
893 case Hexagon::J2_jumpfnewpt:
895 case Hexagon::J2_jumpt:
896 case Hexagon::J2_jumptnew:
897 case Hexagon::J2_jumptnewpt:
902 case Hexagon::J2_jump:
921 if (!Test.
is(0) && !Test.
is(1))
925 if (!Test.
is(!Negated)) {
937 bool HexagonEvaluator::evaluateLoad(
const MachineInstr *MI,
941 assert(MI->
mayLoad() &&
"A load that mayn't?");
946 using namespace Hexagon;
954 case L2_loadalignb_pbr:
955 case L2_loadalignb_pcr:
956 case L2_loadalignb_pi:
958 case L2_loadalignh_pbr:
959 case L2_loadalignh_pcr:
960 case L2_loadalignh_pi:
962 case L2_loadbsw2_pbr:
963 case L2_loadbsw2_pci:
964 case L2_loadbsw2_pcr:
966 case L2_loadbsw4_pbr:
967 case L2_loadbsw4_pci:
968 case L2_loadbsw4_pcr:
971 case L2_loadbzw2_pbr:
972 case L2_loadbzw2_pci:
973 case L2_loadbzw2_pcr:
975 case L2_loadbzw4_pbr:
976 case L2_loadbzw4_pci:
977 case L2_loadbzw4_pcr:
1001 case L4_loadrub_abs:
1025 case L2_loadruh_pbr:
1026 case L2_loadruh_pci:
1027 case L2_loadruh_pcr:
1030 case L4_loadruh_abs:
1043 case L2_loadw_locked:
1059 case L4_loadd_locked:
1070 assert(MD.isReg() && MD.isDef());
1074 assert(W >= BitNum && BitNum > 0);
1077 for (uint16_t i = 0; i < BitNum; ++i)
1082 for (uint16_t i = BitNum; i < W; ++i)
1085 for (uint16_t i = BitNum; i < W; ++i)
1094 bool HexagonEvaluator::evaluateFormalCopy(
const MachineInstr *MI,
1102 assert(RD.Sub == 0);
1109 uint16_t EW = F->second.Width;
1118 if (F->second.Type == ExtType::SExt)
1120 else if (F->second.Type == ExtType::ZExt)
1128 unsigned HexagonEvaluator::getNextPhysReg(
unsigned PReg,
unsigned Width)
const {
1129 using namespace Hexagon;
1130 bool Is64 = DoubleRegsRegClass.contains(PReg);
1131 assert(PReg == 0 || Is64 || IntRegsRegClass.contains(PReg));
1133 static const unsigned Phys32[] = { R0, R1,
R2, R3,
R4, R5 };
1134 static const unsigned Phys64[] = { D0, D1, D2 };
1135 const unsigned Num32 =
sizeof(Phys32)/
sizeof(
unsigned);
1136 const unsigned Num64 =
sizeof(Phys64)/
sizeof(
unsigned);
1140 return (Width <= 32) ? Phys32[0] : Phys64[0];
1144 unsigned Idx32 = 0, Idx64 = 0;
1146 while (Idx32 < Num32) {
1147 if (Phys32[Idx32] == PReg)
1153 while (Idx64 < Num64) {
1154 if (Phys64[Idx64] == PReg)
1162 return (Idx32+1 < Num32) ? Phys32[Idx32+1] : 0;
1163 return (Idx64+1 < Num64) ? Phys64[Idx64+1] : 0;
1167 unsigned HexagonEvaluator::getVirtRegFor(
unsigned PReg)
const {
1170 if (
I->first == PReg)
LLVM Argument representation.
const TargetRegisterInfo & TRI
RegisterCell & fill(uint16_t B, uint16_t E, const BitValue &V)
Sign extended before/after call.
livein_iterator livein_end() const
MachineBasicBlock * getMBB() const
RegisterCell eASR(const RegisterCell &A1, uint16_t Sh) const
static RegisterCell self(unsigned Reg, uint16_t Width)
bool isBlockAddress() const
isBlockAddress - Tests if this is a MO_BlockAddress operand.
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
BitTracker::BitMask mask(unsigned Reg, unsigned Sub) const override
uint16_t getRegBitWidth(const RegisterRef &RR) const
RegisterCell eXOR(const RegisterCell &A1, const RegisterCell &A2) const
const HexagonInstrInfo & TII
bool hasAttribute(unsigned Index, Attribute::AttrKind Kind) const
Return true if the attribute exists at the given index.
RegisterCell eAND(const RegisterCell &A1, const RegisterCell &A2) const
HexagonEvaluator(const HexagonRegisterInfo &tri, MachineRegisterInfo &mri, const HexagonInstrInfo &tii, MachineFunction &mf)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
void putCell(const RegisterRef &RR, RegisterCell RC, CellMapType &M) const
RegisterCell eXTR(const RegisterCell &A1, uint16_t B, uint16_t E) const
bool isJTI() const
isJTI - Tests if this is a MO_JumpTableIndex operand.
const HexagonInstrInfo * TII
bool isPredicated(const MachineInstr *MI) const override
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
const TargetRegisterClass * getRegClass(unsigned Reg) const
getRegClass - Return the register class of the specified virtual register.
Reg
All possible values of the reg field in the ModR/M byte.
unsigned getNumOperands() const
Access to explicit operands of the instruction.
bool isCPI() const
isCPI - Tests if this is a MO_ConstantPoolIndex operand.
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
RegisterCell eMLS(const RegisterCell &A1, const RegisterCell &A2) const
PrintReg - Helper class for printing registers on a raw_ostream.
bool is(unsigned T) const
bool insert(const value_type &X)
Insert a new element into the SetVector.
RegisterCell eSUB(const RegisterCell &A1, const RegisterCell &A2) const
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
The instances of the Type class are immutable: once they are created, they are never changed...
RegisterCell eSXT(const RegisterCell &A1, uint16_t FromN) const
const MachineOperand & getOperand(unsigned i) const
RegisterCell eASL(const RegisterCell &A1, uint16_t Sh) const
bool isSymbol() const
isSymbol - Tests if this is a MO_ExternalSymbol operand.
RegisterCell getCell(const RegisterRef &RR, const CellMapType &M) const
Zero extended before/after call.
RegisterCell eCTB(const RegisterCell &A1, bool B, uint16_t W) const
RegisterCell eZXT(const RegisterCell &A1, uint16_t FromN) const
RegisterCell eCLB(const RegisterCell &A1, bool B, uint16_t W) const
unsigned getSubReg() const
bool isPointerTy() const
isPointerTy - True if this is an instance of PointerType.
DenseMapIterator< unsigned, ExtType, DenseMapInfo< unsigned >, detail::DenseMapPair< unsigned, ExtType >, true > const_iterator
RegisterCell eADD(const RegisterCell &A1, const RegisterCell &A2) const
RegisterCell eORL(const RegisterCell &A1, const RegisterCell &A2) const
unsigned getIntegerBitWidth() const
static BitValue self(const BitRef &Self=BitRef())
MachineOperand class - Representation of each machine instruction operand.
unsigned getObjectAlignment(int ObjectIdx) const
Return the alignment of the specified stack object.
Module.h This file contains the declarations for the Module class.
Type * getType() const
All values are typed, get the type of this value.
RegisterCell eLSR(const RegisterCell &A1, uint16_t Sh) const
livein_iterator livein_begin() const
MachineRegisterInfo & MRI
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
unsigned Log2_32(uint32_t Value)
Log2_32 - This function returns the floor log base 2 of the specified value, -1 if the value is zero...
AttributeSet getAttributes() const
Return the attribute list for this Function.
bool isIntegerTy() const
isIntegerTy - True if this is an instance of IntegerType.
RegisterCell & insert(const RegisterCell &RC, const BitMask &M)
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
Representation of each machine instruction.
static bool isPhysicalRegister(unsigned Reg)
isPhysicalRegister - Return true if the specified register number is in the physical register namespa...
RegisterCell & cat(const RegisterCell &RC)
BitTracker::RegisterRef RegisterRef
RegisterCell eMLU(const RegisterCell &A1, const RegisterCell &A2) const
APFloat abs(APFloat X)
Returns the absolute value of the argument.
iterator find(const KeyT &Val)
bool evaluate(const MachineInstr *MI, const CellMapType &Inputs, CellMapType &Outputs) const override
RegisterCell eIMM(int64_t V, uint16_t W) const
BitTracker::CellMapType CellMapType
std::vector< std::pair< unsigned, unsigned > >::const_iterator livein_iterator
A vector that has set insertion semantics.
RegisterCell eNOT(const RegisterCell &A1) const
bool meet(const RegisterCell &RC, unsigned SelfR)
static RegisterCell ref(const RegisterCell &C)
BitTracker::RegisterCell RegisterCell
static BitValue ref(const BitValue &V)
RegisterCell eINS(const RegisterCell &A1, const RegisterCell &A2, uint16_t AtN) const