0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
1 //===-- MipsSEInstrInfo.cpp - Mips32/64 Instruction Information -----------===//
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
2 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
3 // The LLVM Compiler Infrastructure
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
4 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
5 // This file is distributed under the University of Illinois Open Source
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
6 // License. See LICENSE.TXT for details.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
7 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
8 //===----------------------------------------------------------------------===//
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
9 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
10 // This file contains the Mips32/64 implementation of the TargetInstrInfo class.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
11 //
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
12 //===----------------------------------------------------------------------===//
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
13
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
14 #include "MipsSEInstrInfo.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
15 #include "InstPrinter/MipsInstPrinter.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
16 #include "MipsMachineFunction.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
17 #include "MipsTargetMachine.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
18 #include "llvm/ADT/STLExtras.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
19 #include "llvm/CodeGen/MachineInstrBuilder.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
20 #include "llvm/CodeGen/MachineRegisterInfo.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
21 #include "llvm/Support/CommandLine.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
22 #include "llvm/Support/ErrorHandling.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
23 #include "llvm/Support/TargetRegistry.h"
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
24
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
25 using namespace llvm;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
26
|
77
|
27 MipsSEInstrInfo::MipsSEInstrInfo(const MipsSubtarget &STI)
|
|
28 : MipsInstrInfo(STI, STI.getRelocationModel() == Reloc::PIC_ ? Mips::B
|
|
29 : Mips::J),
|
95
|
30 RI() {}
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
31
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
32 const MipsRegisterInfo &MipsSEInstrInfo::getRegisterInfo() const {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
33 return RI;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
34 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
35
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
36 /// isLoadFromStackSlot - If the specified machine instruction is a direct
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
37 /// load from a stack slot, return the virtual or physical register number of
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
38 /// the destination along with the FrameIndex of the loaded stack slot. If
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
39 /// not, return 0. This predicate must return 0 if the instruction has
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
40 /// any side effects other than loading from the stack slot.
|
83
|
41 unsigned MipsSEInstrInfo::isLoadFromStackSlot(const MachineInstr *MI,
|
|
42 int &FrameIndex) const {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
43 unsigned Opc = MI->getOpcode();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
44
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
45 if ((Opc == Mips::LW) || (Opc == Mips::LD) ||
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
46 (Opc == Mips::LWC1) || (Opc == Mips::LDC1) || (Opc == Mips::LDC164)) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
47 if ((MI->getOperand(1).isFI()) && // is a stack slot
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
48 (MI->getOperand(2).isImm()) && // the imm is zero
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
49 (isZeroImm(MI->getOperand(2)))) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
50 FrameIndex = MI->getOperand(1).getIndex();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
51 return MI->getOperand(0).getReg();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
52 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
53 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
54
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
55 return 0;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
56 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
57
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
58 /// isStoreToStackSlot - If the specified machine instruction is a direct
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
59 /// store to a stack slot, return the virtual or physical register number of
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
60 /// the source reg along with the FrameIndex of the loaded stack slot. If
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
61 /// not, return 0. This predicate must return 0 if the instruction has
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
62 /// any side effects other than storing to the stack slot.
|
83
|
63 unsigned MipsSEInstrInfo::isStoreToStackSlot(const MachineInstr *MI,
|
|
64 int &FrameIndex) const {
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
65 unsigned Opc = MI->getOpcode();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
66
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
67 if ((Opc == Mips::SW) || (Opc == Mips::SD) ||
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
68 (Opc == Mips::SWC1) || (Opc == Mips::SDC1) || (Opc == Mips::SDC164)) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
69 if ((MI->getOperand(1).isFI()) && // is a stack slot
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
70 (MI->getOperand(2).isImm()) && // the imm is zero
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
71 (isZeroImm(MI->getOperand(2)))) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
72 FrameIndex = MI->getOperand(1).getIndex();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
73 return MI->getOperand(0).getReg();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
74 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
75 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
76 return 0;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
77 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
78
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
79 void MipsSEInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
80 MachineBasicBlock::iterator I, DebugLoc DL,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
81 unsigned DestReg, unsigned SrcReg,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
82 bool KillSrc) const {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
83 unsigned Opc = 0, ZeroReg = 0;
|
77
|
84 bool isMicroMips = Subtarget.inMicroMipsMode();
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
85
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
86 if (Mips::GPR32RegClass.contains(DestReg)) { // Copy to CPU Reg.
|
77
|
87 if (Mips::GPR32RegClass.contains(SrcReg)) {
|
|
88 if (isMicroMips)
|
|
89 Opc = Mips::MOVE16_MM;
|
|
90 else
|
95
|
91 Opc = Mips::OR, ZeroReg = Mips::ZERO;
|
77
|
92 } else if (Mips::CCRRegClass.contains(SrcReg))
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
93 Opc = Mips::CFC1;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
94 else if (Mips::FGR32RegClass.contains(SrcReg))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
95 Opc = Mips::MFC1;
|
77
|
96 else if (Mips::HI32RegClass.contains(SrcReg)) {
|
|
97 Opc = isMicroMips ? Mips::MFHI16_MM : Mips::MFHI;
|
|
98 SrcReg = 0;
|
|
99 } else if (Mips::LO32RegClass.contains(SrcReg)) {
|
|
100 Opc = isMicroMips ? Mips::MFLO16_MM : Mips::MFLO;
|
|
101 SrcReg = 0;
|
|
102 } else if (Mips::HI32DSPRegClass.contains(SrcReg))
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
103 Opc = Mips::MFHI_DSP;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
104 else if (Mips::LO32DSPRegClass.contains(SrcReg))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
105 Opc = Mips::MFLO_DSP;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
106 else if (Mips::DSPCCRegClass.contains(SrcReg)) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
107 BuildMI(MBB, I, DL, get(Mips::RDDSP), DestReg).addImm(1 << 4)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
108 .addReg(SrcReg, RegState::Implicit | getKillRegState(KillSrc));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
109 return;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
110 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
111 else if (Mips::MSACtrlRegClass.contains(SrcReg))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
112 Opc = Mips::CFCMSA;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
113 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
114 else if (Mips::GPR32RegClass.contains(SrcReg)) { // Copy from CPU Reg.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
115 if (Mips::CCRRegClass.contains(DestReg))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
116 Opc = Mips::CTC1;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
117 else if (Mips::FGR32RegClass.contains(DestReg))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
118 Opc = Mips::MTC1;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
119 else if (Mips::HI32RegClass.contains(DestReg))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
120 Opc = Mips::MTHI, DestReg = 0;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
121 else if (Mips::LO32RegClass.contains(DestReg))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
122 Opc = Mips::MTLO, DestReg = 0;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
123 else if (Mips::HI32DSPRegClass.contains(DestReg))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
124 Opc = Mips::MTHI_DSP;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
125 else if (Mips::LO32DSPRegClass.contains(DestReg))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
126 Opc = Mips::MTLO_DSP;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
127 else if (Mips::DSPCCRegClass.contains(DestReg)) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
128 BuildMI(MBB, I, DL, get(Mips::WRDSP))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
129 .addReg(SrcReg, getKillRegState(KillSrc)).addImm(1 << 4)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
130 .addReg(DestReg, RegState::ImplicitDefine);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
131 return;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
132 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
133 else if (Mips::MSACtrlRegClass.contains(DestReg))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
134 Opc = Mips::CTCMSA;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
135 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
136 else if (Mips::FGR32RegClass.contains(DestReg, SrcReg))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
137 Opc = Mips::FMOV_S;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
138 else if (Mips::AFGR64RegClass.contains(DestReg, SrcReg))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
139 Opc = Mips::FMOV_D32;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
140 else if (Mips::FGR64RegClass.contains(DestReg, SrcReg))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
141 Opc = Mips::FMOV_D64;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
142 else if (Mips::GPR64RegClass.contains(DestReg)) { // Copy to CPU64 Reg.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
143 if (Mips::GPR64RegClass.contains(SrcReg))
|
95
|
144 Opc = Mips::OR64, ZeroReg = Mips::ZERO_64;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
145 else if (Mips::HI64RegClass.contains(SrcReg))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
146 Opc = Mips::MFHI64, SrcReg = 0;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
147 else if (Mips::LO64RegClass.contains(SrcReg))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
148 Opc = Mips::MFLO64, SrcReg = 0;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
149 else if (Mips::FGR64RegClass.contains(SrcReg))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
150 Opc = Mips::DMFC1;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
151 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
152 else if (Mips::GPR64RegClass.contains(SrcReg)) { // Copy from CPU64 Reg.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
153 if (Mips::HI64RegClass.contains(DestReg))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
154 Opc = Mips::MTHI64, DestReg = 0;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
155 else if (Mips::LO64RegClass.contains(DestReg))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
156 Opc = Mips::MTLO64, DestReg = 0;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
157 else if (Mips::FGR64RegClass.contains(DestReg))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
158 Opc = Mips::DMTC1;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
159 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
160 else if (Mips::MSA128BRegClass.contains(DestReg)) { // Copy to MSA reg
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
161 if (Mips::MSA128BRegClass.contains(SrcReg))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
162 Opc = Mips::MOVE_V;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
163 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
164
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
165 assert(Opc && "Cannot copy registers");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
166
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
167 MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(Opc));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
168
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
169 if (DestReg)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
170 MIB.addReg(DestReg, RegState::Define);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
171
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
172 if (SrcReg)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
173 MIB.addReg(SrcReg, getKillRegState(KillSrc));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
174
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
175 if (ZeroReg)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
176 MIB.addReg(ZeroReg);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
177 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
178
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
179 void MipsSEInstrInfo::
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
180 storeRegToStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
181 unsigned SrcReg, bool isKill, int FI,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
182 const TargetRegisterClass *RC, const TargetRegisterInfo *TRI,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
183 int64_t Offset) const {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
184 DebugLoc DL;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
185 MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOStore);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
186
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
187 unsigned Opc = 0;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
188
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
189 if (Mips::GPR32RegClass.hasSubClassEq(RC))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
190 Opc = Mips::SW;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
191 else if (Mips::GPR64RegClass.hasSubClassEq(RC))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
192 Opc = Mips::SD;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
193 else if (Mips::ACC64RegClass.hasSubClassEq(RC))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
194 Opc = Mips::STORE_ACC64;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
195 else if (Mips::ACC64DSPRegClass.hasSubClassEq(RC))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
196 Opc = Mips::STORE_ACC64DSP;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
197 else if (Mips::ACC128RegClass.hasSubClassEq(RC))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
198 Opc = Mips::STORE_ACC128;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
199 else if (Mips::DSPCCRegClass.hasSubClassEq(RC))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
200 Opc = Mips::STORE_CCOND_DSP;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
201 else if (Mips::FGR32RegClass.hasSubClassEq(RC))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
202 Opc = Mips::SWC1;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
203 else if (Mips::AFGR64RegClass.hasSubClassEq(RC))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
204 Opc = Mips::SDC1;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
205 else if (Mips::FGR64RegClass.hasSubClassEq(RC))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
206 Opc = Mips::SDC164;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
207 else if (RC->hasType(MVT::v16i8))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
208 Opc = Mips::ST_B;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
209 else if (RC->hasType(MVT::v8i16) || RC->hasType(MVT::v8f16))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
210 Opc = Mips::ST_H;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
211 else if (RC->hasType(MVT::v4i32) || RC->hasType(MVT::v4f32))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
212 Opc = Mips::ST_W;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
213 else if (RC->hasType(MVT::v2i64) || RC->hasType(MVT::v2f64))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
214 Opc = Mips::ST_D;
|
100
|
215 else if (Mips::LO32RegClass.hasSubClassEq(RC))
|
|
216 Opc = Mips::SW;
|
|
217 else if (Mips::LO64RegClass.hasSubClassEq(RC))
|
|
218 Opc = Mips::SD;
|
|
219 else if (Mips::HI32RegClass.hasSubClassEq(RC))
|
|
220 Opc = Mips::SW;
|
|
221 else if (Mips::HI64RegClass.hasSubClassEq(RC))
|
|
222 Opc = Mips::SD;
|
|
223
|
|
224 // Hi, Lo are normally caller save but they are callee save
|
|
225 // for interrupt handling.
|
|
226 const Function *Func = MBB.getParent()->getFunction();
|
|
227 if (Func->hasFnAttribute("interrupt")) {
|
|
228 if (Mips::HI32RegClass.hasSubClassEq(RC)) {
|
|
229 BuildMI(MBB, I, DL, get(Mips::MFHI), Mips::K0);
|
|
230 SrcReg = Mips::K0;
|
|
231 } else if (Mips::HI64RegClass.hasSubClassEq(RC)) {
|
|
232 BuildMI(MBB, I, DL, get(Mips::MFHI64), Mips::K0_64);
|
|
233 SrcReg = Mips::K0_64;
|
|
234 } else if (Mips::LO32RegClass.hasSubClassEq(RC)) {
|
|
235 BuildMI(MBB, I, DL, get(Mips::MFLO), Mips::K0);
|
|
236 SrcReg = Mips::K0;
|
|
237 } else if (Mips::LO64RegClass.hasSubClassEq(RC)) {
|
|
238 BuildMI(MBB, I, DL, get(Mips::MFLO64), Mips::K0_64);
|
|
239 SrcReg = Mips::K0_64;
|
|
240 }
|
|
241 }
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
242
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
243 assert(Opc && "Register class not handled!");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
244 BuildMI(MBB, I, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
245 .addFrameIndex(FI).addImm(Offset).addMemOperand(MMO);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
246 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
247
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
248 void MipsSEInstrInfo::
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
249 loadRegFromStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
250 unsigned DestReg, int FI, const TargetRegisterClass *RC,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
251 const TargetRegisterInfo *TRI, int64_t Offset) const {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
252 DebugLoc DL;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
253 if (I != MBB.end()) DL = I->getDebugLoc();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
254 MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOLoad);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
255 unsigned Opc = 0;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
256
|
100
|
257 const Function *Func = MBB.getParent()->getFunction();
|
|
258 bool ReqIndirectLoad = Func->hasFnAttribute("interrupt") &&
|
|
259 (DestReg == Mips::LO0 || DestReg == Mips::LO0_64 ||
|
|
260 DestReg == Mips::HI0 || DestReg == Mips::HI0_64);
|
|
261
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
262 if (Mips::GPR32RegClass.hasSubClassEq(RC))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
263 Opc = Mips::LW;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
264 else if (Mips::GPR64RegClass.hasSubClassEq(RC))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
265 Opc = Mips::LD;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
266 else if (Mips::ACC64RegClass.hasSubClassEq(RC))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
267 Opc = Mips::LOAD_ACC64;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
268 else if (Mips::ACC64DSPRegClass.hasSubClassEq(RC))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
269 Opc = Mips::LOAD_ACC64DSP;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
270 else if (Mips::ACC128RegClass.hasSubClassEq(RC))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
271 Opc = Mips::LOAD_ACC128;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
272 else if (Mips::DSPCCRegClass.hasSubClassEq(RC))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
273 Opc = Mips::LOAD_CCOND_DSP;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
274 else if (Mips::FGR32RegClass.hasSubClassEq(RC))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
275 Opc = Mips::LWC1;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
276 else if (Mips::AFGR64RegClass.hasSubClassEq(RC))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
277 Opc = Mips::LDC1;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
278 else if (Mips::FGR64RegClass.hasSubClassEq(RC))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
279 Opc = Mips::LDC164;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
280 else if (RC->hasType(MVT::v16i8))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
281 Opc = Mips::LD_B;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
282 else if (RC->hasType(MVT::v8i16) || RC->hasType(MVT::v8f16))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
283 Opc = Mips::LD_H;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
284 else if (RC->hasType(MVT::v4i32) || RC->hasType(MVT::v4f32))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
285 Opc = Mips::LD_W;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
286 else if (RC->hasType(MVT::v2i64) || RC->hasType(MVT::v2f64))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
287 Opc = Mips::LD_D;
|
100
|
288 else if (Mips::HI32RegClass.hasSubClassEq(RC))
|
|
289 Opc = Mips::LW;
|
|
290 else if (Mips::HI64RegClass.hasSubClassEq(RC))
|
|
291 Opc = Mips::LD;
|
|
292 else if (Mips::LO32RegClass.hasSubClassEq(RC))
|
|
293 Opc = Mips::LW;
|
|
294 else if (Mips::LO64RegClass.hasSubClassEq(RC))
|
|
295 Opc = Mips::LD;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
296
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
297 assert(Opc && "Register class not handled!");
|
100
|
298
|
|
299 if (!ReqIndirectLoad)
|
|
300 BuildMI(MBB, I, DL, get(Opc), DestReg)
|
|
301 .addFrameIndex(FI)
|
|
302 .addImm(Offset)
|
|
303 .addMemOperand(MMO);
|
|
304 else {
|
|
305 // Load HI/LO through K0. Notably the DestReg is encoded into the
|
|
306 // instruction itself.
|
|
307 unsigned Reg = Mips::K0;
|
|
308 unsigned LdOp = Mips::MTLO;
|
|
309 if (DestReg == Mips::HI0)
|
|
310 LdOp = Mips::MTHI;
|
|
311
|
|
312 if (Subtarget.getABI().ArePtrs64bit()) {
|
|
313 Reg = Mips::K0_64;
|
|
314 if (DestReg == Mips::HI0_64)
|
|
315 LdOp = Mips::MTHI64;
|
|
316 else
|
|
317 LdOp = Mips::MTLO64;
|
|
318 }
|
|
319
|
|
320 BuildMI(MBB, I, DL, get(Opc), Reg)
|
|
321 .addFrameIndex(FI)
|
|
322 .addImm(Offset)
|
|
323 .addMemOperand(MMO);
|
|
324 BuildMI(MBB, I, DL, get(LdOp)).addReg(Reg);
|
|
325 }
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
326 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
327
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
328 bool MipsSEInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
329 MachineBasicBlock &MBB = *MI->getParent();
|
77
|
330 bool isMicroMips = Subtarget.inMicroMipsMode();
|
|
331 unsigned Opc;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
332
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
333 switch(MI->getDesc().getOpcode()) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
334 default:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
335 return false;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
336 case Mips::RetRA:
|
77
|
337 expandRetRA(MBB, MI);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
338 break;
|
100
|
339 case Mips::ERet:
|
|
340 expandERet(MBB, MI);
|
|
341 break;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
342 case Mips::PseudoMFHI:
|
77
|
343 Opc = isMicroMips ? Mips::MFHI16_MM : Mips::MFHI;
|
|
344 expandPseudoMFHiLo(MBB, MI, Opc);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
345 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
346 case Mips::PseudoMFLO:
|
77
|
347 Opc = isMicroMips ? Mips::MFLO16_MM : Mips::MFLO;
|
|
348 expandPseudoMFHiLo(MBB, MI, Opc);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
349 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
350 case Mips::PseudoMFHI64:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
351 expandPseudoMFHiLo(MBB, MI, Mips::MFHI64);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
352 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
353 case Mips::PseudoMFLO64:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
354 expandPseudoMFHiLo(MBB, MI, Mips::MFLO64);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
355 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
356 case Mips::PseudoMTLOHI:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
357 expandPseudoMTLoHi(MBB, MI, Mips::MTLO, Mips::MTHI, false);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
358 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
359 case Mips::PseudoMTLOHI64:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
360 expandPseudoMTLoHi(MBB, MI, Mips::MTLO64, Mips::MTHI64, false);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
361 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
362 case Mips::PseudoMTLOHI_DSP:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
363 expandPseudoMTLoHi(MBB, MI, Mips::MTLO_DSP, Mips::MTHI_DSP, true);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
364 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
365 case Mips::PseudoCVT_S_W:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
366 expandCvtFPInt(MBB, MI, Mips::CVT_S_W, Mips::MTC1, false);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
367 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
368 case Mips::PseudoCVT_D32_W:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
369 expandCvtFPInt(MBB, MI, Mips::CVT_D32_W, Mips::MTC1, false);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
370 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
371 case Mips::PseudoCVT_S_L:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
372 expandCvtFPInt(MBB, MI, Mips::CVT_S_L, Mips::DMTC1, true);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
373 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
374 case Mips::PseudoCVT_D64_W:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
375 expandCvtFPInt(MBB, MI, Mips::CVT_D64_W, Mips::MTC1, true);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
376 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
377 case Mips::PseudoCVT_D64_L:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
378 expandCvtFPInt(MBB, MI, Mips::CVT_D64_L, Mips::DMTC1, true);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
379 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
380 case Mips::BuildPairF64:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
381 expandBuildPairF64(MBB, MI, false);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
382 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
383 case Mips::BuildPairF64_64:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
384 expandBuildPairF64(MBB, MI, true);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
385 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
386 case Mips::ExtractElementF64:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
387 expandExtractElementF64(MBB, MI, false);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
388 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
389 case Mips::ExtractElementF64_64:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
390 expandExtractElementF64(MBB, MI, true);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
391 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
392 case Mips::MIPSeh_return32:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
393 case Mips::MIPSeh_return64:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
394 expandEhReturn(MBB, MI);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
395 break;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
396 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
397
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
398 MBB.erase(MI);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
399 return true;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
400 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
401
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
402 /// getOppositeBranchOpc - Return the inverse of the specified
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
403 /// opcode, e.g. turning BEQ to BNE.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
404 unsigned MipsSEInstrInfo::getOppositeBranchOpc(unsigned Opc) const {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
405 switch (Opc) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
406 default: llvm_unreachable("Illegal opcode!");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
407 case Mips::BEQ: return Mips::BNE;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
408 case Mips::BNE: return Mips::BEQ;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
409 case Mips::BGTZ: return Mips::BLEZ;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
410 case Mips::BGEZ: return Mips::BLTZ;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
411 case Mips::BLTZ: return Mips::BGEZ;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
412 case Mips::BLEZ: return Mips::BGTZ;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
413 case Mips::BEQ64: return Mips::BNE64;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
414 case Mips::BNE64: return Mips::BEQ64;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
415 case Mips::BGTZ64: return Mips::BLEZ64;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
416 case Mips::BGEZ64: return Mips::BLTZ64;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
417 case Mips::BLTZ64: return Mips::BGEZ64;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
418 case Mips::BLEZ64: return Mips::BGTZ64;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
419 case Mips::BC1T: return Mips::BC1F;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
420 case Mips::BC1F: return Mips::BC1T;
|
83
|
421 case Mips::BEQZC_MM: return Mips::BNEZC_MM;
|
|
422 case Mips::BNEZC_MM: return Mips::BEQZC_MM;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
423 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
424 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
425
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
426 /// Adjust SP by Amount bytes.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
427 void MipsSEInstrInfo::adjustStackPtr(unsigned SP, int64_t Amount,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
428 MachineBasicBlock &MBB,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
429 MachineBasicBlock::iterator I) const {
|
95
|
430 MipsABIInfo ABI = Subtarget.getABI();
|
|
431 DebugLoc DL;
|
|
432 unsigned ADDu = ABI.GetPtrAdduOp();
|
|
433 unsigned ADDiu = ABI.GetPtrAddiuOp();
|
|
434
|
|
435 if (Amount == 0)
|
|
436 return;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
437
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
438 if (isInt<16>(Amount))// addi sp, sp, amount
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
439 BuildMI(MBB, I, DL, get(ADDiu), SP).addReg(SP).addImm(Amount);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
440 else { // Expand immediate that doesn't fit in 16-bit.
|
77
|
441 unsigned Reg = loadImmediate(Amount, MBB, I, DL, nullptr);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
442 BuildMI(MBB, I, DL, get(ADDu), SP).addReg(SP).addReg(Reg, RegState::Kill);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
443 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
444 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
445
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
446 /// This function generates the sequence of instructions needed to get the
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
447 /// result of adding register REG and immediate IMM.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
448 unsigned
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
449 MipsSEInstrInfo::loadImmediate(int64_t Imm, MachineBasicBlock &MBB,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
450 MachineBasicBlock::iterator II, DebugLoc DL,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
451 unsigned *NewImm) const {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
452 MipsAnalyzeImmediate AnalyzeImm;
|
77
|
453 const MipsSubtarget &STI = Subtarget;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
454 MachineRegisterInfo &RegInfo = MBB.getParent()->getRegInfo();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
455 unsigned Size = STI.isABI_N64() ? 64 : 32;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
456 unsigned LUi = STI.isABI_N64() ? Mips::LUi64 : Mips::LUi;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
457 unsigned ZEROReg = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
458 const TargetRegisterClass *RC = STI.isABI_N64() ?
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
459 &Mips::GPR64RegClass : &Mips::GPR32RegClass;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
460 bool LastInstrIsADDiu = NewImm;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
461
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
462 const MipsAnalyzeImmediate::InstSeq &Seq =
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
463 AnalyzeImm.Analyze(Imm, Size, LastInstrIsADDiu);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
464 MipsAnalyzeImmediate::InstSeq::const_iterator Inst = Seq.begin();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
465
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
466 assert(Seq.size() && (!LastInstrIsADDiu || (Seq.size() > 1)));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
467
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
468 // The first instruction can be a LUi, which is different from other
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
469 // instructions (ADDiu, ORI and SLL) in that it does not have a register
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
470 // operand.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
471 unsigned Reg = RegInfo.createVirtualRegister(RC);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
472
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
473 if (Inst->Opc == LUi)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
474 BuildMI(MBB, II, DL, get(LUi), Reg).addImm(SignExtend64<16>(Inst->ImmOpnd));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
475 else
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
476 BuildMI(MBB, II, DL, get(Inst->Opc), Reg).addReg(ZEROReg)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
477 .addImm(SignExtend64<16>(Inst->ImmOpnd));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
478
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
479 // Build the remaining instructions in Seq.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
480 for (++Inst; Inst != Seq.end() - LastInstrIsADDiu; ++Inst)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
481 BuildMI(MBB, II, DL, get(Inst->Opc), Reg).addReg(Reg, RegState::Kill)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
482 .addImm(SignExtend64<16>(Inst->ImmOpnd));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
483
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
484 if (LastInstrIsADDiu)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
485 *NewImm = Inst->ImmOpnd;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
486
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
487 return Reg;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
488 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
489
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
490 unsigned MipsSEInstrInfo::getAnalyzableBrOpc(unsigned Opc) const {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
491 return (Opc == Mips::BEQ || Opc == Mips::BNE || Opc == Mips::BGTZ ||
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
492 Opc == Mips::BGEZ || Opc == Mips::BLTZ || Opc == Mips::BLEZ ||
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
493 Opc == Mips::BEQ64 || Opc == Mips::BNE64 || Opc == Mips::BGTZ64 ||
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
494 Opc == Mips::BGEZ64 || Opc == Mips::BLTZ64 || Opc == Mips::BLEZ64 ||
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
495 Opc == Mips::BC1T || Opc == Mips::BC1F || Opc == Mips::B ||
|
83
|
496 Opc == Mips::J || Opc == Mips::BEQZC_MM || Opc == Mips::BNEZC_MM) ?
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
497 Opc : 0;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
498 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
499
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
500 void MipsSEInstrInfo::expandRetRA(MachineBasicBlock &MBB,
|
77
|
501 MachineBasicBlock::iterator I) const {
|
|
502 if (Subtarget.isGP64bit())
|
|
503 BuildMI(MBB, I, I->getDebugLoc(), get(Mips::PseudoReturn64))
|
|
504 .addReg(Mips::RA_64);
|
|
505 else
|
|
506 BuildMI(MBB, I, I->getDebugLoc(), get(Mips::PseudoReturn)).addReg(Mips::RA);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
507 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
508
|
100
|
509 void MipsSEInstrInfo::expandERet(MachineBasicBlock &MBB,
|
|
510 MachineBasicBlock::iterator I) const {
|
|
511 BuildMI(MBB, I, I->getDebugLoc(), get(Mips::ERET));
|
|
512 }
|
|
513
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
514 std::pair<bool, bool>
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
515 MipsSEInstrInfo::compareOpndSize(unsigned Opc,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
516 const MachineFunction &MF) const {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
517 const MCInstrDesc &Desc = get(Opc);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
518 assert(Desc.NumOperands == 2 && "Unary instruction expected.");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
519 const MipsRegisterInfo *RI = &getRegisterInfo();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
520 unsigned DstRegSize = getRegClass(Desc, 0, RI, MF)->getSize();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
521 unsigned SrcRegSize = getRegClass(Desc, 1, RI, MF)->getSize();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
522
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
523 return std::make_pair(DstRegSize > SrcRegSize, DstRegSize < SrcRegSize);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
524 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
525
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
526 void MipsSEInstrInfo::expandPseudoMFHiLo(MachineBasicBlock &MBB,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
527 MachineBasicBlock::iterator I,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
528 unsigned NewOpc) const {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
529 BuildMI(MBB, I, I->getDebugLoc(), get(NewOpc), I->getOperand(0).getReg());
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
530 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
531
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
532 void MipsSEInstrInfo::expandPseudoMTLoHi(MachineBasicBlock &MBB,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
533 MachineBasicBlock::iterator I,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
534 unsigned LoOpc,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
535 unsigned HiOpc,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
536 bool HasExplicitDef) const {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
537 // Expand
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
538 // lo_hi pseudomtlohi $gpr0, $gpr1
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
539 // to these two instructions:
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
540 // mtlo $gpr0
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
541 // mthi $gpr1
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
542
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
543 DebugLoc DL = I->getDebugLoc();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
544 const MachineOperand &SrcLo = I->getOperand(1), &SrcHi = I->getOperand(2);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
545 MachineInstrBuilder LoInst = BuildMI(MBB, I, DL, get(LoOpc));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
546 MachineInstrBuilder HiInst = BuildMI(MBB, I, DL, get(HiOpc));
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
547
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
548 // Add lo/hi registers if the mtlo/hi instructions created have explicit
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
549 // def registers.
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
550 if (HasExplicitDef) {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
551 unsigned DstReg = I->getOperand(0).getReg();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
552 unsigned DstLo = getRegisterInfo().getSubReg(DstReg, Mips::sub_lo);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
553 unsigned DstHi = getRegisterInfo().getSubReg(DstReg, Mips::sub_hi);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
554 LoInst.addReg(DstLo, RegState::Define);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
555 HiInst.addReg(DstHi, RegState::Define);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
556 }
|
100
|
557
|
|
558 LoInst.addReg(SrcLo.getReg(), getKillRegState(SrcLo.isKill()));
|
|
559 HiInst.addReg(SrcHi.getReg(), getKillRegState(SrcHi.isKill()));
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
560 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
561
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
562 void MipsSEInstrInfo::expandCvtFPInt(MachineBasicBlock &MBB,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
563 MachineBasicBlock::iterator I,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
564 unsigned CvtOpc, unsigned MovOpc,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
565 bool IsI64) const {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
566 const MCInstrDesc &CvtDesc = get(CvtOpc), &MovDesc = get(MovOpc);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
567 const MachineOperand &Dst = I->getOperand(0), &Src = I->getOperand(1);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
568 unsigned DstReg = Dst.getReg(), SrcReg = Src.getReg(), TmpReg = DstReg;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
569 unsigned KillSrc = getKillRegState(Src.isKill());
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
570 DebugLoc DL = I->getDebugLoc();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
571 bool DstIsLarger, SrcIsLarger;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
572
|
77
|
573 std::tie(DstIsLarger, SrcIsLarger) =
|
|
574 compareOpndSize(CvtOpc, *MBB.getParent());
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
575
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
576 if (DstIsLarger)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
577 TmpReg = getRegisterInfo().getSubReg(DstReg, Mips::sub_lo);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
578
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
579 if (SrcIsLarger)
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
580 DstReg = getRegisterInfo().getSubReg(DstReg, Mips::sub_lo);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
581
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
582 BuildMI(MBB, I, DL, MovDesc, TmpReg).addReg(SrcReg, KillSrc);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
583 BuildMI(MBB, I, DL, CvtDesc, DstReg).addReg(TmpReg, RegState::Kill);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
584 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
585
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
586 void MipsSEInstrInfo::expandExtractElementF64(MachineBasicBlock &MBB,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
587 MachineBasicBlock::iterator I,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
588 bool FP64) const {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
589 unsigned DstReg = I->getOperand(0).getReg();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
590 unsigned SrcReg = I->getOperand(1).getReg();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
591 unsigned N = I->getOperand(2).getImm();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
592 DebugLoc dl = I->getDebugLoc();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
593
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
594 assert(N < 2 && "Invalid immediate");
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
595 unsigned SubIdx = N ? Mips::sub_hi : Mips::sub_lo;
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
596 unsigned SubReg = getRegisterInfo().getSubReg(SrcReg, SubIdx);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
597
|
77
|
598 // FPXX on MIPS-II or MIPS32r1 should have been handled with a spill/reload
|
|
599 // in MipsSEFrameLowering.cpp.
|
|
600 assert(!(Subtarget.isABI_FPXX() && !Subtarget.hasMips32r2()));
|
|
601
|
|
602 // FP64A (FP64 with nooddspreg) should have been handled with a spill/reload
|
|
603 // in MipsSEFrameLowering.cpp.
|
|
604 assert(!(Subtarget.isFP64bit() && !Subtarget.useOddSPReg()));
|
|
605
|
|
606 if (SubIdx == Mips::sub_hi && Subtarget.hasMTHC1()) {
|
|
607 // FIXME: Strictly speaking MFHC1 only reads the top 32-bits however, we
|
|
608 // claim to read the whole 64-bits as part of a white lie used to
|
|
609 // temporarily work around a widespread bug in the -mfp64 support.
|
|
610 // The problem is that none of the 32-bit fpu ops mention the fact
|
|
611 // that they clobber the upper 32-bits of the 64-bit FPR. Fixing that
|
|
612 // requires a major overhaul of the FPU implementation which can't
|
|
613 // be done right now due to time constraints.
|
|
614 // MFHC1 is one of two instructions that are affected since they are
|
|
615 // the only instructions that don't read the lower 32-bits.
|
|
616 // We therefore pretend that it reads the bottom 32-bits to
|
|
617 // artificially create a dependency and prevent the scheduler
|
|
618 // changing the behaviour of the code.
|
|
619 BuildMI(MBB, I, dl, get(FP64 ? Mips::MFHC1_D64 : Mips::MFHC1_D32), DstReg)
|
|
620 .addReg(SrcReg);
|
|
621 } else
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
622 BuildMI(MBB, I, dl, get(Mips::MFC1), DstReg).addReg(SubReg);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
623 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
624
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
625 void MipsSEInstrInfo::expandBuildPairF64(MachineBasicBlock &MBB,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
626 MachineBasicBlock::iterator I,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
627 bool FP64) const {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
628 unsigned DstReg = I->getOperand(0).getReg();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
629 unsigned LoReg = I->getOperand(1).getReg(), HiReg = I->getOperand(2).getReg();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
630 const MCInstrDesc& Mtc1Tdd = get(Mips::MTC1);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
631 DebugLoc dl = I->getDebugLoc();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
632 const TargetRegisterInfo &TRI = getRegisterInfo();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
633
|
77
|
634 // When mthc1 is available, use:
|
|
635 // mtc1 Lo, $fp
|
|
636 // mthc1 Hi, $fp
|
|
637 //
|
|
638 // Otherwise, for O32 FPXX ABI:
|
|
639 // spill + reload via ldc1
|
|
640 // This case is handled by the frame lowering code.
|
|
641 //
|
|
642 // Otherwise, for FP32:
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
643 // mtc1 Lo, $fp
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
644 // mtc1 Hi, $fp + 1
|
77
|
645 //
|
|
646 // The case where dmtc1 is available doesn't need to be handled here
|
|
647 // because it never creates a BuildPairF64 node.
|
|
648
|
|
649 // FPXX on MIPS-II or MIPS32r1 should have been handled with a spill/reload
|
|
650 // in MipsSEFrameLowering.cpp.
|
|
651 assert(!(Subtarget.isABI_FPXX() && !Subtarget.hasMips32r2()));
|
|
652
|
|
653 // FP64A (FP64 with nooddspreg) should have been handled with a spill/reload
|
|
654 // in MipsSEFrameLowering.cpp.
|
|
655 assert(!(Subtarget.isFP64bit() && !Subtarget.useOddSPReg()));
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
656
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
657 BuildMI(MBB, I, dl, Mtc1Tdd, TRI.getSubReg(DstReg, Mips::sub_lo))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
658 .addReg(LoReg);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
659
|
77
|
660 if (Subtarget.hasMTHC1()) {
|
|
661 // FIXME: The .addReg(DstReg) is a white lie used to temporarily work
|
|
662 // around a widespread bug in the -mfp64 support.
|
|
663 // The problem is that none of the 32-bit fpu ops mention the fact
|
|
664 // that they clobber the upper 32-bits of the 64-bit FPR. Fixing that
|
|
665 // requires a major overhaul of the FPU implementation which can't
|
|
666 // be done right now due to time constraints.
|
|
667 // MTHC1 is one of two instructions that are affected since they are
|
|
668 // the only instructions that don't read the lower 32-bits.
|
|
669 // We therefore pretend that it reads the bottom 32-bits to
|
|
670 // artificially create a dependency and prevent the scheduler
|
|
671 // changing the behaviour of the code.
|
|
672 BuildMI(MBB, I, dl, get(FP64 ? Mips::MTHC1_D64 : Mips::MTHC1_D32), DstReg)
|
|
673 .addReg(DstReg)
|
|
674 .addReg(HiReg);
|
|
675 } else if (Subtarget.isABI_FPXX())
|
|
676 llvm_unreachable("BuildPairF64 not expanded in frame lowering code!");
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
677 else
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
678 BuildMI(MBB, I, dl, Mtc1Tdd, TRI.getSubReg(DstReg, Mips::sub_hi))
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
679 .addReg(HiReg);
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
680 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
681
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
682 void MipsSEInstrInfo::expandEhReturn(MachineBasicBlock &MBB,
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
683 MachineBasicBlock::iterator I) const {
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
684 // This pseudo instruction is generated as part of the lowering of
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
685 // ISD::EH_RETURN. We convert it to a stack increment by OffsetReg, and
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
686 // indirect jump to TargetReg
|
95
|
687 MipsABIInfo ABI = Subtarget.getABI();
|
|
688 unsigned ADDU = ABI.GetPtrAdduOp();
|
77
|
689 unsigned SP = Subtarget.isGP64bit() ? Mips::SP_64 : Mips::SP;
|
|
690 unsigned RA = Subtarget.isGP64bit() ? Mips::RA_64 : Mips::RA;
|
|
691 unsigned T9 = Subtarget.isGP64bit() ? Mips::T9_64 : Mips::T9;
|
|
692 unsigned ZERO = Subtarget.isGP64bit() ? Mips::ZERO_64 : Mips::ZERO;
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
693 unsigned OffsetReg = I->getOperand(0).getReg();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
694 unsigned TargetReg = I->getOperand(1).getReg();
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
695
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
696 // addu $ra, $v0, $zero
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
697 // addu $sp, $sp, $v1
|
77
|
698 // jr $ra (via RetRA)
|
|
699 const TargetMachine &TM = MBB.getParent()->getTarget();
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
700 if (TM.getRelocationModel() == Reloc::PIC_)
|
83
|
701 BuildMI(MBB, I, I->getDebugLoc(), get(ADDU), T9)
|
77
|
702 .addReg(TargetReg)
|
|
703 .addReg(ZERO);
|
83
|
704 BuildMI(MBB, I, I->getDebugLoc(), get(ADDU), RA)
|
77
|
705 .addReg(TargetReg)
|
|
706 .addReg(ZERO);
|
83
|
707 BuildMI(MBB, I, I->getDebugLoc(), get(ADDU), SP).addReg(SP).addReg(OffsetReg);
|
77
|
708 expandRetRA(MBB, I);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
709 }
|
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
710
|
77
|
711 const MipsInstrInfo *llvm::createMipsSEInstrInfo(const MipsSubtarget &STI) {
|
|
712 return new MipsSEInstrInfo(STI);
|
0
Kaito Tokumori <e105711@ie.u-ryukyu.ac.jp>
parents:
diff
changeset
|
713 }
|