annotate lib/Target/AVR/AVRInstrInfo.cpp @ 148:63bd29f05246

merged
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Wed, 14 Aug 2019 19:46:37 +0900
parents c2174574ed3a
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
120
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
1 //===-- AVRInstrInfo.cpp - AVR Instruction Information --------------------===//
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
2 //
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 121
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 121
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 121
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
120
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
6 //
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
7 //===----------------------------------------------------------------------===//
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
8 //
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
9 // This file contains the AVR implementation of the TargetInstrInfo class.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
10 //
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
11 //===----------------------------------------------------------------------===//
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
12
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
13 #include "AVRInstrInfo.h"
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
14
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
15 #include "llvm/ADT/STLExtras.h"
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
16 #include "llvm/CodeGen/MachineConstantPool.h"
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
17 #include "llvm/CodeGen/MachineFrameInfo.h"
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
18 #include "llvm/CodeGen/MachineInstrBuilder.h"
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
19 #include "llvm/CodeGen/MachineMemOperand.h"
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
20 #include "llvm/IR/Constants.h"
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
21 #include "llvm/IR/Function.h"
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
22 #include "llvm/MC/MCContext.h"
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
23 #include "llvm/Support/Debug.h"
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
24 #include "llvm/Support/ErrorHandling.h"
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
25 #include "llvm/Support/TargetRegistry.h"
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
26
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
27 #include "AVR.h"
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
28 #include "AVRMachineFunctionInfo.h"
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
29 #include "AVRRegisterInfo.h"
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
30 #include "AVRTargetMachine.h"
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
31 #include "MCTargetDesc/AVRMCTargetDesc.h"
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
32
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
33 #define GET_INSTRINFO_CTOR_DTOR
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
34 #include "AVRGenInstrInfo.inc"
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
35
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
36 namespace llvm {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
37
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
38 AVRInstrInfo::AVRInstrInfo()
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
39 : AVRGenInstrInfo(AVR::ADJCALLSTACKDOWN, AVR::ADJCALLSTACKUP), RI() {}
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
40
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
41 void AVRInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
42 MachineBasicBlock::iterator MI,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
43 const DebugLoc &DL, unsigned DestReg,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
44 unsigned SrcReg, bool KillSrc) const {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
45 const AVRSubtarget &STI = MBB.getParent()->getSubtarget<AVRSubtarget>();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
46 const AVRRegisterInfo &TRI = *STI.getRegisterInfo();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
47 unsigned Opc;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
48
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
49 // Not all AVR devices support the 16-bit `MOVW` instruction.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
50 if (AVR::DREGSRegClass.contains(DestReg, SrcReg)) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
51 if (STI.hasMOVW()) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
52 BuildMI(MBB, MI, DL, get(AVR::MOVWRdRr), DestReg)
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
53 .addReg(SrcReg, getKillRegState(KillSrc));
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
54 } else {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
55 unsigned DestLo, DestHi, SrcLo, SrcHi;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
56
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
57 TRI.splitReg(DestReg, DestLo, DestHi);
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
58 TRI.splitReg(SrcReg, SrcLo, SrcHi);
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
59
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
60 // Copy each individual register with the `MOV` instruction.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
61 BuildMI(MBB, MI, DL, get(AVR::MOVRdRr), DestLo)
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
62 .addReg(SrcLo, getKillRegState(KillSrc));
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
63 BuildMI(MBB, MI, DL, get(AVR::MOVRdRr), DestHi)
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
64 .addReg(SrcHi, getKillRegState(KillSrc));
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
65 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
66 } else {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
67 if (AVR::GPR8RegClass.contains(DestReg, SrcReg)) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
68 Opc = AVR::MOVRdRr;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
69 } else if (SrcReg == AVR::SP && AVR::DREGSRegClass.contains(DestReg)) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
70 Opc = AVR::SPREAD;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
71 } else if (DestReg == AVR::SP && AVR::DREGSRegClass.contains(SrcReg)) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
72 Opc = AVR::SPWRITE;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
73 } else {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
74 llvm_unreachable("Impossible reg-to-reg copy");
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
75 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
76
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
77 BuildMI(MBB, MI, DL, get(Opc), DestReg)
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
78 .addReg(SrcReg, getKillRegState(KillSrc));
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
79 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
80 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
81
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
82 unsigned AVRInstrInfo::isLoadFromStackSlot(const MachineInstr &MI,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
83 int &FrameIndex) const {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
84 switch (MI.getOpcode()) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
85 case AVR::LDDRdPtrQ:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
86 case AVR::LDDWRdYQ: { //:FIXME: remove this once PR13375 gets fixed
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
87 if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
88 MI.getOperand(2).getImm() == 0) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
89 FrameIndex = MI.getOperand(1).getIndex();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
90 return MI.getOperand(0).getReg();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
91 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
92 break;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
93 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
94 default:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
95 break;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
96 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
97
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
98 return 0;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
99 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
100
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
101 unsigned AVRInstrInfo::isStoreToStackSlot(const MachineInstr &MI,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
102 int &FrameIndex) const {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
103 switch (MI.getOpcode()) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
104 case AVR::STDPtrQRr:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
105 case AVR::STDWPtrQRr: {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
106 if (MI.getOperand(0).isFI() && MI.getOperand(1).isImm() &&
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
107 MI.getOperand(1).getImm() == 0) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
108 FrameIndex = MI.getOperand(0).getIndex();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
109 return MI.getOperand(2).getReg();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
110 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
111 break;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
112 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
113 default:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
114 break;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
115 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
116
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
117 return 0;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
118 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
119
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
120 void AVRInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
121 MachineBasicBlock::iterator MI,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
122 unsigned SrcReg, bool isKill,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
123 int FrameIndex,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
124 const TargetRegisterClass *RC,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
125 const TargetRegisterInfo *TRI) const {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
126 MachineFunction &MF = *MBB.getParent();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
127 AVRMachineFunctionInfo *AFI = MF.getInfo<AVRMachineFunctionInfo>();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
128
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
129 AFI->setHasSpills(true);
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
130
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
131 DebugLoc DL;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
132 if (MI != MBB.end()) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
133 DL = MI->getDebugLoc();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
134 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
135
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
136 const MachineFrameInfo &MFI = MF.getFrameInfo();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
137
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
138 MachineMemOperand *MMO = MF.getMachineMemOperand(
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
139 MachinePointerInfo::getFixedStack(MF, FrameIndex),
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
140 MachineMemOperand::MOStore, MFI.getObjectSize(FrameIndex),
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
141 MFI.getObjectAlignment(FrameIndex));
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
142
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
143 unsigned Opcode = 0;
121
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
144 if (TRI->isTypeLegalForClass(*RC, MVT::i8)) {
120
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
145 Opcode = AVR::STDPtrQRr;
121
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
146 } else if (TRI->isTypeLegalForClass(*RC, MVT::i16)) {
120
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
147 Opcode = AVR::STDWPtrQRr;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
148 } else {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
149 llvm_unreachable("Cannot store this register into a stack slot!");
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
150 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
151
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
152 BuildMI(MBB, MI, DL, get(Opcode))
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
153 .addFrameIndex(FrameIndex)
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
154 .addImm(0)
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
155 .addReg(SrcReg, getKillRegState(isKill))
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
156 .addMemOperand(MMO);
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
157 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
158
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
159 void AVRInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
160 MachineBasicBlock::iterator MI,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
161 unsigned DestReg, int FrameIndex,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
162 const TargetRegisterClass *RC,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
163 const TargetRegisterInfo *TRI) const {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
164 DebugLoc DL;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
165 if (MI != MBB.end()) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
166 DL = MI->getDebugLoc();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
167 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
168
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
169 MachineFunction &MF = *MBB.getParent();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
170 const MachineFrameInfo &MFI = MF.getFrameInfo();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
171
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
172 MachineMemOperand *MMO = MF.getMachineMemOperand(
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
173 MachinePointerInfo::getFixedStack(MF, FrameIndex),
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
174 MachineMemOperand::MOLoad, MFI.getObjectSize(FrameIndex),
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
175 MFI.getObjectAlignment(FrameIndex));
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
176
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
177 unsigned Opcode = 0;
121
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
178 if (TRI->isTypeLegalForClass(*RC, MVT::i8)) {
120
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
179 Opcode = AVR::LDDRdPtrQ;
121
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
180 } else if (TRI->isTypeLegalForClass(*RC, MVT::i16)) {
120
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
181 // Opcode = AVR::LDDWRdPtrQ;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
182 //:FIXME: remove this once PR13375 gets fixed
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
183 Opcode = AVR::LDDWRdYQ;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
184 } else {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
185 llvm_unreachable("Cannot load this register from a stack slot!");
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
186 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
187
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
188 BuildMI(MBB, MI, DL, get(Opcode), DestReg)
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
189 .addFrameIndex(FrameIndex)
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
190 .addImm(0)
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
191 .addMemOperand(MMO);
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
192 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
193
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
194 const MCInstrDesc &AVRInstrInfo::getBrCond(AVRCC::CondCodes CC) const {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
195 switch (CC) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
196 default:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
197 llvm_unreachable("Unknown condition code!");
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
198 case AVRCC::COND_EQ:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
199 return get(AVR::BREQk);
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
200 case AVRCC::COND_NE:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
201 return get(AVR::BRNEk);
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
202 case AVRCC::COND_GE:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
203 return get(AVR::BRGEk);
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
204 case AVRCC::COND_LT:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
205 return get(AVR::BRLTk);
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
206 case AVRCC::COND_SH:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
207 return get(AVR::BRSHk);
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
208 case AVRCC::COND_LO:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
209 return get(AVR::BRLOk);
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
210 case AVRCC::COND_MI:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
211 return get(AVR::BRMIk);
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
212 case AVRCC::COND_PL:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
213 return get(AVR::BRPLk);
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
214 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
215 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
216
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
217 AVRCC::CondCodes AVRInstrInfo::getCondFromBranchOpc(unsigned Opc) const {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
218 switch (Opc) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
219 default:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
220 return AVRCC::COND_INVALID;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
221 case AVR::BREQk:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
222 return AVRCC::COND_EQ;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
223 case AVR::BRNEk:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
224 return AVRCC::COND_NE;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
225 case AVR::BRSHk:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
226 return AVRCC::COND_SH;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
227 case AVR::BRLOk:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
228 return AVRCC::COND_LO;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
229 case AVR::BRMIk:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
230 return AVRCC::COND_MI;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
231 case AVR::BRPLk:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
232 return AVRCC::COND_PL;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
233 case AVR::BRGEk:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
234 return AVRCC::COND_GE;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
235 case AVR::BRLTk:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
236 return AVRCC::COND_LT;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
237 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
238 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
239
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
240 AVRCC::CondCodes AVRInstrInfo::getOppositeCondition(AVRCC::CondCodes CC) const {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
241 switch (CC) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
242 default:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
243 llvm_unreachable("Invalid condition!");
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
244 case AVRCC::COND_EQ:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
245 return AVRCC::COND_NE;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
246 case AVRCC::COND_NE:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
247 return AVRCC::COND_EQ;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
248 case AVRCC::COND_SH:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
249 return AVRCC::COND_LO;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
250 case AVRCC::COND_LO:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
251 return AVRCC::COND_SH;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
252 case AVRCC::COND_GE:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
253 return AVRCC::COND_LT;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
254 case AVRCC::COND_LT:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
255 return AVRCC::COND_GE;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
256 case AVRCC::COND_MI:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
257 return AVRCC::COND_PL;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
258 case AVRCC::COND_PL:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
259 return AVRCC::COND_MI;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
260 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
261 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
262
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
263 bool AVRInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
264 MachineBasicBlock *&TBB,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
265 MachineBasicBlock *&FBB,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
266 SmallVectorImpl<MachineOperand> &Cond,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
267 bool AllowModify) const {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
268 // Start from the bottom of the block and work up, examining the
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
269 // terminator instructions.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
270 MachineBasicBlock::iterator I = MBB.end();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
271 MachineBasicBlock::iterator UnCondBrIter = MBB.end();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
272
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
273 while (I != MBB.begin()) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
274 --I;
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 121
diff changeset
275 if (I->isDebugInstr()) {
120
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
276 continue;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
277 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
278
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
279 // Working from the bottom, when we see a non-terminator
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
280 // instruction, we're done.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
281 if (!isUnpredicatedTerminator(*I)) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
282 break;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
283 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
284
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
285 // A terminator that isn't a branch can't easily be handled
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
286 // by this analysis.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
287 if (!I->getDesc().isBranch()) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
288 return true;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
289 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
290
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
291 // Handle unconditional branches.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
292 //:TODO: add here jmp
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
293 if (I->getOpcode() == AVR::RJMPk) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
294 UnCondBrIter = I;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
295
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
296 if (!AllowModify) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
297 TBB = I->getOperand(0).getMBB();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
298 continue;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
299 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
300
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
301 // If the block has any instructions after a JMP, delete them.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
302 while (std::next(I) != MBB.end()) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
303 std::next(I)->eraseFromParent();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
304 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
305
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
306 Cond.clear();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
307 FBB = 0;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
308
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
309 // Delete the JMP if it's equivalent to a fall-through.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
310 if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
311 TBB = 0;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
312 I->eraseFromParent();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
313 I = MBB.end();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
314 UnCondBrIter = MBB.end();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
315 continue;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
316 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
317
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
318 // TBB is used to indicate the unconditinal destination.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
319 TBB = I->getOperand(0).getMBB();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
320 continue;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
321 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
322
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
323 // Handle conditional branches.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
324 AVRCC::CondCodes BranchCode = getCondFromBranchOpc(I->getOpcode());
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
325 if (BranchCode == AVRCC::COND_INVALID) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
326 return true; // Can't handle indirect branch.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
327 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
328
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
329 // Working from the bottom, handle the first conditional branch.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
330 if (Cond.empty()) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
331 MachineBasicBlock *TargetBB = I->getOperand(0).getMBB();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
332 if (AllowModify && UnCondBrIter != MBB.end() &&
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
333 MBB.isLayoutSuccessor(TargetBB)) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
334 // If we can modify the code and it ends in something like:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
335 //
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
336 // jCC L1
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
337 // jmp L2
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
338 // L1:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
339 // ...
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
340 // L2:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
341 //
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
342 // Then we can change this to:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
343 //
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
344 // jnCC L2
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
345 // L1:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
346 // ...
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
347 // L2:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
348 //
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
349 // Which is a bit more efficient.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
350 // We conditionally jump to the fall-through block.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
351 BranchCode = getOppositeCondition(BranchCode);
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
352 unsigned JNCC = getBrCond(BranchCode).getOpcode();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
353 MachineBasicBlock::iterator OldInst = I;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
354
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
355 BuildMI(MBB, UnCondBrIter, MBB.findDebugLoc(I), get(JNCC))
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
356 .addMBB(UnCondBrIter->getOperand(0).getMBB());
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
357 BuildMI(MBB, UnCondBrIter, MBB.findDebugLoc(I), get(AVR::RJMPk))
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
358 .addMBB(TargetBB);
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
359
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
360 OldInst->eraseFromParent();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
361 UnCondBrIter->eraseFromParent();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
362
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
363 // Restart the analysis.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
364 UnCondBrIter = MBB.end();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
365 I = MBB.end();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
366 continue;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
367 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
368
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
369 FBB = TBB;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
370 TBB = I->getOperand(0).getMBB();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
371 Cond.push_back(MachineOperand::CreateImm(BranchCode));
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
372 continue;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
373 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
374
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
375 // Handle subsequent conditional branches. Only handle the case where all
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
376 // conditional branches branch to the same destination.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
377 assert(Cond.size() == 1);
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
378 assert(TBB);
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
379
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
380 // Only handle the case where all conditional branches branch to
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
381 // the same destination.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
382 if (TBB != I->getOperand(0).getMBB()) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
383 return true;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
384 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
385
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
386 AVRCC::CondCodes OldBranchCode = (AVRCC::CondCodes)Cond[0].getImm();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
387 // If the conditions are the same, we can leave them alone.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
388 if (OldBranchCode == BranchCode) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
389 continue;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
390 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
391
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
392 return true;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
393 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
394
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
395 return false;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
396 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
397
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
398 unsigned AVRInstrInfo::insertBranch(MachineBasicBlock &MBB,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
399 MachineBasicBlock *TBB,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
400 MachineBasicBlock *FBB,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
401 ArrayRef<MachineOperand> Cond,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
402 const DebugLoc &DL,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
403 int *BytesAdded) const {
121
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
404 if (BytesAdded) *BytesAdded = 0;
120
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
405
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
406 // Shouldn't be a fall through.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
407 assert(TBB && "insertBranch must not be told to insert a fallthrough");
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
408 assert((Cond.size() == 1 || Cond.size() == 0) &&
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
409 "AVR branch conditions have one component!");
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
410
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
411 if (Cond.empty()) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
412 assert(!FBB && "Unconditional branch with multiple successors!");
121
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
413 auto &MI = *BuildMI(&MBB, DL, get(AVR::RJMPk)).addMBB(TBB);
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
414 if (BytesAdded)
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
415 *BytesAdded += getInstSizeInBytes(MI);
120
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
416 return 1;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
417 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
418
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
419 // Conditional branch.
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
420 unsigned Count = 0;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
421 AVRCC::CondCodes CC = (AVRCC::CondCodes)Cond[0].getImm();
121
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
422 auto &CondMI = *BuildMI(&MBB, DL, getBrCond(CC)).addMBB(TBB);
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
423
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
424 if (BytesAdded) *BytesAdded += getInstSizeInBytes(CondMI);
120
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
425 ++Count;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
426
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
427 if (FBB) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
428 // Two-way Conditional branch. Insert the second branch.
121
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
429 auto &MI = *BuildMI(&MBB, DL, get(AVR::RJMPk)).addMBB(FBB);
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
430 if (BytesAdded) *BytesAdded += getInstSizeInBytes(MI);
120
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
431 ++Count;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
432 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
433
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
434 return Count;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
435 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
436
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
437 unsigned AVRInstrInfo::removeBranch(MachineBasicBlock &MBB,
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
438 int *BytesRemoved) const {
121
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
439 if (BytesRemoved) *BytesRemoved = 0;
120
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
440
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
441 MachineBasicBlock::iterator I = MBB.end();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
442 unsigned Count = 0;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
443
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
444 while (I != MBB.begin()) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
445 --I;
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 121
diff changeset
446 if (I->isDebugInstr()) {
120
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
447 continue;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
448 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
449 //:TODO: add here the missing jmp instructions once they are implemented
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
450 // like jmp, {e}ijmp, and other cond branches, ...
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
451 if (I->getOpcode() != AVR::RJMPk &&
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
452 getCondFromBranchOpc(I->getOpcode()) == AVRCC::COND_INVALID) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
453 break;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
454 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
455
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
456 // Remove the branch.
121
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
457 if (BytesRemoved) *BytesRemoved += getInstSizeInBytes(*I);
120
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
458 I->eraseFromParent();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
459 I = MBB.end();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
460 ++Count;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
461 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
462
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
463 return Count;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
464 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
465
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
466 bool AVRInstrInfo::reverseBranchCondition(
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
467 SmallVectorImpl<MachineOperand> &Cond) const {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
468 assert(Cond.size() == 1 && "Invalid AVR branch condition!");
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
469
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
470 AVRCC::CondCodes CC = static_cast<AVRCC::CondCodes>(Cond[0].getImm());
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
471 Cond[0].setImm(getOppositeCondition(CC));
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
472
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
473 return false;
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
474 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
475
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
476 unsigned AVRInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
477 unsigned Opcode = MI.getOpcode();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
478
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
479 switch (Opcode) {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
480 // A regular instruction
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
481 default: {
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
482 const MCInstrDesc &Desc = get(Opcode);
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
483 return Desc.getSize();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
484 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
485 case TargetOpcode::EH_LABEL:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
486 case TargetOpcode::IMPLICIT_DEF:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
487 case TargetOpcode::KILL:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
488 case TargetOpcode::DBG_VALUE:
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
489 return 0;
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 121
diff changeset
490 case TargetOpcode::INLINEASM:
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 121
diff changeset
491 case TargetOpcode::INLINEASM_BR: {
120
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
492 const MachineFunction &MF = *MI.getParent()->getParent();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
493 const AVRTargetMachine &TM = static_cast<const AVRTargetMachine&>(MF.getTarget());
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
494 const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
495 const TargetInstrInfo &TII = *STI.getInstrInfo();
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
496
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
497 return TII.getInlineAsmLength(MI.getOperand(0).getSymbolName(),
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
498 *TM.getMCAsmInfo());
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
499 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
500 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
501 }
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
502
121
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
503 MachineBasicBlock *
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
504 AVRInstrInfo::getBranchDestBlock(const MachineInstr &MI) const {
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
505 switch (MI.getOpcode()) {
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
506 default:
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
507 llvm_unreachable("unexpected opcode!");
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
508 case AVR::JMPk:
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
509 case AVR::CALLk:
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
510 case AVR::RCALLk:
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
511 case AVR::RJMPk:
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
512 case AVR::BREQk:
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
513 case AVR::BRNEk:
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
514 case AVR::BRSHk:
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
515 case AVR::BRLOk:
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
516 case AVR::BRMIk:
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
517 case AVR::BRPLk:
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
518 case AVR::BRGEk:
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
519 case AVR::BRLTk:
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
520 return MI.getOperand(0).getMBB();
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
521 case AVR::BRBSsk:
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
522 case AVR::BRBCsk:
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
523 return MI.getOperand(1).getMBB();
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
524 case AVR::SBRCRrB:
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
525 case AVR::SBRSRrB:
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
526 case AVR::SBICAb:
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
527 case AVR::SBISAb:
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
528 llvm_unreachable("unimplemented branch instructions");
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
529 }
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
530 }
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
531
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
532 bool AVRInstrInfo::isBranchOffsetInRange(unsigned BranchOp,
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
533 int64_t BrOffset) const {
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
534
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
535 switch (BranchOp) {
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
536 default:
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
537 llvm_unreachable("unexpected opcode!");
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
538 case AVR::JMPk:
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
539 case AVR::CALLk:
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
540 return true;
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
541 case AVR::RCALLk:
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
542 case AVR::RJMPk:
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
543 return isIntN(13, BrOffset);
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
544 case AVR::BRBSsk:
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
545 case AVR::BRBCsk:
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
546 case AVR::BREQk:
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
547 case AVR::BRNEk:
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
548 case AVR::BRSHk:
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
549 case AVR::BRLOk:
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
550 case AVR::BRMIk:
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
551 case AVR::BRPLk:
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
552 case AVR::BRGEk:
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
553 case AVR::BRLTk:
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
554 return isIntN(7, BrOffset);
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
555 }
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
556 }
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
557
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
558 unsigned AVRInstrInfo::insertIndirectBranch(MachineBasicBlock &MBB,
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
559 MachineBasicBlock &NewDestBB,
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
560 const DebugLoc &DL,
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
561 int64_t BrOffset,
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
562 RegScavenger *RS) const {
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
563 // This method inserts a *direct* branch (JMP), despite its name.
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
564 // LLVM calls this method to fixup unconditional branches; it never calls
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
565 // insertBranch or some hypothetical "insertDirectBranch".
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
566 // See lib/CodeGen/RegisterRelaxation.cpp for details.
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
567 // We end up here when a jump is too long for a RJMP instruction.
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
568 auto &MI = *BuildMI(&MBB, DL, get(AVR::JMPk)).addMBB(&NewDestBB);
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
569
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
570 return getInstSizeInBytes(MI);
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
571 }
803732b1fca8 LLVM 5.0
kono
parents: 120
diff changeset
572
120
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
573 } // end of namespace llvm
1172e4bd9c6f update 4.0.0
mir3636
parents:
diff changeset
574