/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/ARM/ARMInstrInfo.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===-- ARMInstrInfo.cpp - ARM Instruction Information --------------------===// |
2 | | // |
3 | | // The LLVM Compiler Infrastructure |
4 | | // |
5 | | // This file is distributed under the University of Illinois Open Source |
6 | | // License. See LICENSE.TXT for details. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | // |
10 | | // This file contains the ARM implementation of the TargetInstrInfo class. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #include "ARMInstrInfo.h" |
15 | | #include "ARM.h" |
16 | | #include "ARMConstantPoolValue.h" |
17 | | #include "ARMMachineFunctionInfo.h" |
18 | | #include "ARMTargetMachine.h" |
19 | | #include "MCTargetDesc/ARMAddressingModes.h" |
20 | | #include "llvm/ADT/STLExtras.h" |
21 | | #include "llvm/CodeGen/LiveVariables.h" |
22 | | #include "llvm/CodeGen/MachineFrameInfo.h" |
23 | | #include "llvm/CodeGen/MachineInstrBuilder.h" |
24 | | #include "llvm/CodeGen/MachineJumpTableInfo.h" |
25 | | #include "llvm/CodeGen/MachineRegisterInfo.h" |
26 | | #include "llvm/IR/Function.h" |
27 | | #include "llvm/IR/GlobalVariable.h" |
28 | | #include "llvm/MC/MCAsmInfo.h" |
29 | | #include "llvm/MC/MCInst.h" |
30 | | using namespace llvm; |
31 | | |
32 | | ARMInstrInfo::ARMInstrInfo(const ARMSubtarget &STI) |
33 | 2.75k | : ARMBaseInstrInfo(STI), RI() {} |
34 | | |
35 | | /// Return the noop instruction to use for a noop. |
36 | 20 | void ARMInstrInfo::getNoop(MCInst &NopInst) const { |
37 | 20 | if (hasNOP()20 ) { |
38 | 15 | NopInst.setOpcode(ARM::HINT); |
39 | 15 | NopInst.addOperand(MCOperand::createImm(0)); |
40 | 15 | NopInst.addOperand(MCOperand::createImm(ARMCC::AL)); |
41 | 15 | NopInst.addOperand(MCOperand::createReg(0)); |
42 | 20 | } else { |
43 | 5 | NopInst.setOpcode(ARM::MOVr); |
44 | 5 | NopInst.addOperand(MCOperand::createReg(ARM::R0)); |
45 | 5 | NopInst.addOperand(MCOperand::createReg(ARM::R0)); |
46 | 5 | NopInst.addOperand(MCOperand::createImm(ARMCC::AL)); |
47 | 5 | NopInst.addOperand(MCOperand::createReg(0)); |
48 | 5 | NopInst.addOperand(MCOperand::createReg(0)); |
49 | 5 | } |
50 | 20 | } |
51 | | |
52 | 0 | unsigned ARMInstrInfo::getUnindexedOpcode(unsigned Opc) const { |
53 | 0 | switch (Opc) { |
54 | 0 | default: |
55 | 0 | break; |
56 | 0 | case ARM::LDR_PRE_IMM: |
57 | 0 | case ARM::LDR_PRE_REG: |
58 | 0 | case ARM::LDR_POST_IMM: |
59 | 0 | case ARM::LDR_POST_REG: |
60 | 0 | return ARM::LDRi12; |
61 | 0 | case ARM::LDRH_PRE: |
62 | 0 | case ARM::LDRH_POST: |
63 | 0 | return ARM::LDRH; |
64 | 0 | case ARM::LDRB_PRE_IMM: |
65 | 0 | case ARM::LDRB_PRE_REG: |
66 | 0 | case ARM::LDRB_POST_IMM: |
67 | 0 | case ARM::LDRB_POST_REG: |
68 | 0 | return ARM::LDRBi12; |
69 | 0 | case ARM::LDRSH_PRE: |
70 | 0 | case ARM::LDRSH_POST: |
71 | 0 | return ARM::LDRSH; |
72 | 0 | case ARM::LDRSB_PRE: |
73 | 0 | case ARM::LDRSB_POST: |
74 | 0 | return ARM::LDRSB; |
75 | 0 | case ARM::STR_PRE_IMM: |
76 | 0 | case ARM::STR_PRE_REG: |
77 | 0 | case ARM::STR_POST_IMM: |
78 | 0 | case ARM::STR_POST_REG: |
79 | 0 | return ARM::STRi12; |
80 | 0 | case ARM::STRH_PRE: |
81 | 0 | case ARM::STRH_POST: |
82 | 0 | return ARM::STRH; |
83 | 0 | case ARM::STRB_PRE_IMM: |
84 | 0 | case ARM::STRB_PRE_REG: |
85 | 0 | case ARM::STRB_POST_IMM: |
86 | 0 | case ARM::STRB_POST_REG: |
87 | 0 | return ARM::STRBi12; |
88 | 0 | } |
89 | 0 |
|
90 | 0 | return 0; |
91 | 0 | } |
92 | | |
93 | 20 | void ARMInstrInfo::expandLoadStackGuard(MachineBasicBlock::iterator MI) const { |
94 | 20 | MachineFunction &MF = *MI->getParent()->getParent(); |
95 | 20 | const ARMSubtarget &Subtarget = MF.getSubtarget<ARMSubtarget>(); |
96 | 20 | const TargetMachine &TM = MF.getTarget(); |
97 | 20 | |
98 | 20 | if (!Subtarget.useMovt(MF)20 ) { |
99 | 6 | if (TM.isPositionIndependent()) |
100 | 2 | expandLoadStackGuardBase(MI, ARM::LDRLIT_ga_pcrel, ARM::LDRi12); |
101 | 6 | else |
102 | 4 | expandLoadStackGuardBase(MI, ARM::LDRLIT_ga_abs, ARM::LDRi12); |
103 | 6 | return; |
104 | 6 | } |
105 | 14 | |
106 | 14 | if (14 !TM.isPositionIndependent()14 ) { |
107 | 4 | expandLoadStackGuardBase(MI, ARM::MOVi32imm, ARM::LDRi12); |
108 | 4 | return; |
109 | 4 | } |
110 | 10 | |
111 | 10 | const GlobalValue *GV = |
112 | 10 | cast<GlobalValue>((*MI->memoperands_begin())->getValue()); |
113 | 10 | |
114 | 10 | if (!Subtarget.isGVIndirectSymbol(GV)10 ) { |
115 | 0 | expandLoadStackGuardBase(MI, ARM::MOV_ga_pcrel, ARM::LDRi12); |
116 | 0 | return; |
117 | 0 | } |
118 | 10 | |
119 | 10 | MachineBasicBlock &MBB = *MI->getParent(); |
120 | 10 | DebugLoc DL = MI->getDebugLoc(); |
121 | 10 | unsigned Reg = MI->getOperand(0).getReg(); |
122 | 10 | MachineInstrBuilder MIB; |
123 | 10 | |
124 | 10 | MIB = BuildMI(MBB, MI, DL, get(ARM::MOV_ga_pcrel_ldr), Reg) |
125 | 10 | .addGlobalAddress(GV, 0, ARMII::MO_NONLAZY); |
126 | 10 | auto Flags = MachineMemOperand::MOLoad | |
127 | 10 | MachineMemOperand::MODereferenceable | |
128 | 10 | MachineMemOperand::MOInvariant; |
129 | 10 | MachineMemOperand *MMO = MBB.getParent()->getMachineMemOperand( |
130 | 10 | MachinePointerInfo::getGOT(*MBB.getParent()), Flags, 4, 4); |
131 | 10 | MIB.addMemOperand(MMO); |
132 | 10 | BuildMI(MBB, MI, DL, get(ARM::LDRi12), Reg) |
133 | 10 | .addReg(Reg, RegState::Kill) |
134 | 10 | .addImm(0) |
135 | 10 | .setMemRefs(MI->memoperands_begin(), MI->memoperands_end()) |
136 | 10 | .add(predOps(ARMCC::AL)); |
137 | 10 | } |