Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/Target/ARM/Thumb1InstrInfo.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- Thumb1InstrInfo.cpp - Thumb-1 Instruction Information -------------===//
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
//
9
// This file contains the Thumb-1 implementation of the TargetInstrInfo class.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "Thumb1InstrInfo.h"
14
#include "ARMSubtarget.h"
15
#include "llvm/CodeGen/MachineFrameInfo.h"
16
#include "llvm/CodeGen/MachineInstrBuilder.h"
17
#include "llvm/CodeGen/MachineMemOperand.h"
18
#include "llvm/MC/MCInst.h"
19
20
using namespace llvm;
21
22
Thumb1InstrInfo::Thumb1InstrInfo(const ARMSubtarget &STI)
23
740
    : ARMBaseInstrInfo(STI), RI() {}
24
25
/// Return the noop instruction to use for a noop.
26
0
void Thumb1InstrInfo::getNoop(MCInst &NopInst) const {
27
0
  NopInst.setOpcode(ARM::tMOVr);
28
0
  NopInst.addOperand(MCOperand::createReg(ARM::R8));
29
0
  NopInst.addOperand(MCOperand::createReg(ARM::R8));
30
0
  NopInst.addOperand(MCOperand::createImm(ARMCC::AL));
31
0
  NopInst.addOperand(MCOperand::createReg(0));
32
0
}
33
34
0
unsigned Thumb1InstrInfo::getUnindexedOpcode(unsigned Opc) const {
35
0
  return 0;
36
0
}
37
38
void Thumb1InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
39
                                  MachineBasicBlock::iterator I,
40
                                  const DebugLoc &DL, unsigned DestReg,
41
3.32k
                                  unsigned SrcReg, bool KillSrc) const {
42
3.32k
  // Need to check the arch.
43
3.32k
  MachineFunction &MF = *MBB.getParent();
44
3.32k
  const ARMSubtarget &st = MF.getSubtarget<ARMSubtarget>();
45
3.32k
46
3.32k
  assert(ARM::GPRRegClass.contains(DestReg, SrcReg) &&
47
3.32k
         "Thumb1 can only copy GPR registers");
48
3.32k
49
3.32k
  if (st.hasV6Ops() || 
ARM::hGPRRegClass.contains(SrcReg)429
50
3.32k
      || 
!ARM::tGPRRegClass.contains(DestReg)351
)
51
2.98k
    BuildMI(MBB, I, DL, get(ARM::tMOVr), DestReg)
52
2.98k
        .addReg(SrcReg, getKillRegState(KillSrc))
53
2.98k
        .add(predOps(ARMCC::AL));
54
342
  else {
55
342
    // FIXME: Can also use 'mov hi, $src; mov $dst, hi',
56
342
    // with hi as either r10 or r11.
57
342
58
342
    const TargetRegisterInfo *RegInfo = st.getRegisterInfo();
59
342
    if (MBB.computeRegisterLiveness(RegInfo, ARM::CPSR, I)
60
342
        == MachineBasicBlock::LQR_Dead) {
61
330
      BuildMI(MBB, I, DL, get(ARM::tMOVSr), DestReg)
62
330
          .addReg(SrcReg, getKillRegState(KillSrc))
63
330
          ->addRegisterDead(ARM::CPSR, RegInfo);
64
330
      return;
65
330
    }
66
12
67
12
    // 'MOV lo, lo' is unpredictable on < v6, so use the stack to do it
68
12
    BuildMI(MBB, I, DL, get(ARM::tPUSH))
69
12
        .add(predOps(ARMCC::AL))
70
12
        .addReg(SrcReg, getKillRegState(KillSrc));
71
12
    BuildMI(MBB, I, DL, get(ARM::tPOP))
72
12
        .add(predOps(ARMCC::AL))
73
12
        .addReg(DestReg, getDefRegState(true));
74
12
  }
75
3.32k
}
76
77
void Thumb1InstrInfo::
78
storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
79
                    unsigned SrcReg, bool isKill, int FI,
80
                    const TargetRegisterClass *RC,
81
1.19k
                    const TargetRegisterInfo *TRI) const {
82
1.19k
  assert((RC == &ARM::tGPRRegClass ||
83
1.19k
          (TargetRegisterInfo::isPhysicalRegister(SrcReg) &&
84
1.19k
           isARMLowRegister(SrcReg))) && "Unknown regclass!");
85
1.19k
86
1.19k
  if (RC == &ARM::tGPRRegClass ||
87
1.19k
      
(0
TargetRegisterInfo::isPhysicalRegister(SrcReg)0
&&
88
1.19k
       
isARMLowRegister(SrcReg)0
)) {
89
1.19k
    DebugLoc DL;
90
1.19k
    if (I != MBB.end()) 
DL = I->getDebugLoc()1.18k
;
91
1.19k
92
1.19k
    MachineFunction &MF = *MBB.getParent();
93
1.19k
    MachineFrameInfo &MFI = MF.getFrameInfo();
94
1.19k
    MachineMemOperand *MMO = MF.getMachineMemOperand(
95
1.19k
        MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOStore,
96
1.19k
        MFI.getObjectSize(FI), MFI.getObjectAlignment(FI));
97
1.19k
    BuildMI(MBB, I, DL, get(ARM::tSTRspi))
98
1.19k
        .addReg(SrcReg, getKillRegState(isKill))
99
1.19k
        .addFrameIndex(FI)
100
1.19k
        .addImm(0)
101
1.19k
        .addMemOperand(MMO)
102
1.19k
        .add(predOps(ARMCC::AL));
103
1.19k
  }
104
1.19k
}
105
106
void Thumb1InstrInfo::
107
loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
108
                     unsigned DestReg, int FI,
109
                     const TargetRegisterClass *RC,
110
1.67k
                     const TargetRegisterInfo *TRI) const {
111
1.67k
  assert((RC->hasSuperClassEq(&ARM::tGPRRegClass) ||
112
1.67k
          (TargetRegisterInfo::isPhysicalRegister(DestReg) &&
113
1.67k
           isARMLowRegister(DestReg))) && "Unknown regclass!");
114
1.67k
115
1.67k
  if (RC->hasSuperClassEq(&ARM::tGPRRegClass) ||
116
1.67k
      
(0
TargetRegisterInfo::isPhysicalRegister(DestReg)0
&&
117
1.67k
       
isARMLowRegister(DestReg)0
)) {
118
1.67k
    DebugLoc DL;
119
1.67k
    if (I != MBB.end()) DL = I->getDebugLoc();
120
1.67k
121
1.67k
    MachineFunction &MF = *MBB.getParent();
122
1.67k
    MachineFrameInfo &MFI = MF.getFrameInfo();
123
1.67k
    MachineMemOperand *MMO = MF.getMachineMemOperand(
124
1.67k
        MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOLoad,
125
1.67k
        MFI.getObjectSize(FI), MFI.getObjectAlignment(FI));
126
1.67k
    BuildMI(MBB, I, DL, get(ARM::tLDRspi), DestReg)
127
1.67k
        .addFrameIndex(FI)
128
1.67k
        .addImm(0)
129
1.67k
        .addMemOperand(MMO)
130
1.67k
        .add(predOps(ARMCC::AL));
131
1.67k
  }
132
1.67k
}
133
134
void Thumb1InstrInfo::expandLoadStackGuard(
135
6
    MachineBasicBlock::iterator MI) const {
136
6
  MachineFunction &MF = *MI->getParent()->getParent();
137
6
  const TargetMachine &TM = MF.getTarget();
138
6
  if (TM.isPositionIndependent())
139
2
    expandLoadStackGuardBase(MI, ARM::tLDRLIT_ga_pcrel, ARM::tLDRi);
140
4
  else
141
4
    expandLoadStackGuardBase(MI, ARM::tLDRLIT_ga_abs, ARM::tLDRi);
142
6
}
143
144
4
bool Thumb1InstrInfo::canCopyGluedNodeDuringSchedule(SDNode *N) const {
145
4
  // In Thumb1 the scheduler may need to schedule a cross-copy between GPRS and CPSR
146
4
  // but this is not always possible there, so allow the Scheduler to clone tADCS and tSBCS
147
4
  // even if they have glue.
148
4
  // FIXME. Actually implement the cross-copy where it is possible (post v6)
149
4
  // because these copies entail more spilling.
150
4
  unsigned Opcode = N->getMachineOpcode();
151
4
  if (Opcode == ARM::tADCS || 
Opcode == ARM::tSBCS0
)
152
4
    return true;
153
0
154
0
  return false;
155
0
}