Deleted Added
full compact
MipsISelDAGToDAG.cpp (199481) MipsISelDAGToDAG.cpp (199511)
1//===-- MipsISelDAGToDAG.cpp - A dag to dag inst selector for Mips --------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//

--- 76 unchanged lines hidden (view full) ---

85
86 SDNode *getGlobalBaseReg();
87 SDNode *Select(SDValue N);
88
89 // Complex Pattern.
90 bool SelectAddr(SDValue Op, SDValue N,
91 SDValue &Base, SDValue &Offset);
92
1//===-- MipsISelDAGToDAG.cpp - A dag to dag inst selector for Mips --------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//

--- 76 unchanged lines hidden (view full) ---

85
86 SDNode *getGlobalBaseReg();
87 SDNode *Select(SDValue N);
88
89 // Complex Pattern.
90 bool SelectAddr(SDValue Op, SDValue N,
91 SDValue &Base, SDValue &Offset);
92
93 SDNode *SelectLoadFp64(SDValue N);
94 SDNode *SelectStoreFp64(SDValue N);
93
94 // getI32Imm - Return a target constant with the specified
95 // value, of type i32.
96 inline SDValue getI32Imm(unsigned Imm) {
97 return CurDAG->getTargetConstant(Imm, MVT::i32);
98 }
99
100

--- 92 unchanged lines hidden (view full) ---

193 }
194 }
195
196 Base = Addr;
197 Offset = CurDAG->getTargetConstant(0, MVT::i32);
198 return true;
199}
200
95
96 // getI32Imm - Return a target constant with the specified
97 // value, of type i32.
98 inline SDValue getI32Imm(unsigned Imm) {
99 return CurDAG->getTargetConstant(Imm, MVT::i32);
100 }
101
102

--- 92 unchanged lines hidden (view full) ---

195 }
196 }
197
198 Base = Addr;
199 Offset = CurDAG->getTargetConstant(0, MVT::i32);
200 return true;
201}
202
203SDNode *MipsDAGToDAGISel::SelectLoadFp64(SDValue N) {
204 MVT::SimpleValueType NVT =
205 N.getNode()->getValueType(0).getSimpleVT().SimpleTy;
206
207 if (!Subtarget.isMips1() || NVT != MVT::f64)
208 return NULL;
209
210 if (!Predicate_unindexedload(N.getNode()) ||
211 !Predicate_load(N.getNode()))
212 return NULL;
213
214 SDValue Chain = N.getOperand(0);
215 SDValue N1 = N.getOperand(1);
216 SDValue Offset0, Offset1, Base;
217
218 if (!SelectAddr(N, N1, Offset0, Base) ||
219 N1.getValueType() != MVT::i32)
220 return NULL;
221
222 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
223 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
224 DebugLoc dl = N.getDebugLoc();
225
226 // The second load should start after for 4 bytes.
227 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Offset0))
228 Offset1 = CurDAG->getTargetConstant(C->getSExtValue()+4, MVT::i32);
229 else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Offset0))
230 Offset1 = CurDAG->getTargetConstantPool(CP->getConstVal(),
231 MVT::i32,
232 CP->getAlignment(),
233 CP->getOffset()+4,
234 CP->getTargetFlags());
235 else
236 return NULL;
237
238 // Instead of:
239 // ldc $f0, X($3)
240 // Generate:
241 // lwc $f0, X($3)
242 // lwc $f1, X+4($3)
243 SDNode *LD0 = CurDAG->getMachineNode(Mips::LWC1, dl, MVT::f32,
244 MVT::Other, Offset0, Base, Chain);
245 SDValue Undef = SDValue(CurDAG->getMachineNode(TargetInstrInfo::IMPLICIT_DEF,
246 dl, NVT), 0);
247 SDValue I0 = CurDAG->getTargetInsertSubreg(Mips::SUBREG_FPEVEN, dl,
248 MVT::f64, Undef, SDValue(LD0, 0));
249
250 SDNode *LD1 = CurDAG->getMachineNode(Mips::LWC1, dl, MVT::f32,
251 MVT::Other, Offset1, Base, SDValue(LD0, 1));
252 SDValue I1 = CurDAG->getTargetInsertSubreg(Mips::SUBREG_FPODD, dl,
253 MVT::f64, I0, SDValue(LD1, 0));
254
255 ReplaceUses(N, I1);
256 ReplaceUses(N.getValue(1), Chain);
257 cast<MachineSDNode>(LD0)->setMemRefs(MemRefs0, MemRefs0 + 1);
258 cast<MachineSDNode>(LD1)->setMemRefs(MemRefs0, MemRefs0 + 1);
259 return I1.getNode();
260}
261
262SDNode *MipsDAGToDAGISel::SelectStoreFp64(SDValue N) {
263
264 if (!Subtarget.isMips1() ||
265 N.getOperand(1).getValueType() != MVT::f64)
266 return NULL;
267
268 SDValue Chain = N.getOperand(0);
269
270 if (!Predicate_unindexedstore(N.getNode()) ||
271 !Predicate_store(N.getNode()))
272 return NULL;
273
274 SDValue N1 = N.getOperand(1);
275 SDValue N2 = N.getOperand(2);
276 SDValue Offset0, Offset1, Base;
277
278 if (!SelectAddr(N, N2, Offset0, Base) ||
279 N1.getValueType() != MVT::f64 ||
280 N2.getValueType() != MVT::i32)
281 return NULL;
282
283 MachineSDNode::mmo_iterator MemRefs0 = MF->allocateMemRefsArray(1);
284 MemRefs0[0] = cast<MemSDNode>(N)->getMemOperand();
285 DebugLoc dl = N.getDebugLoc();
286
287 // Get the even and odd part from the f64 register
288 SDValue FPOdd = CurDAG->getTargetExtractSubreg(Mips::SUBREG_FPODD,
289 dl, MVT::f32, N1);
290 SDValue FPEven = CurDAG->getTargetExtractSubreg(Mips::SUBREG_FPEVEN,
291 dl, MVT::f32, N1);
292
293 // The second store should start after for 4 bytes.
294 if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Offset0))
295 Offset1 = CurDAG->getTargetConstant(C->getSExtValue()+4, MVT::i32);
296 else
297 return NULL;
298
299 // Instead of:
300 // sdc $f0, X($3)
301 // Generate:
302 // swc $f0, X($3)
303 // swc $f1, X+4($3)
304 SDValue Ops0[] = { FPEven, Offset0, Base, Chain };
305 Chain = SDValue(CurDAG->getMachineNode(Mips::SWC1, dl,
306 MVT::Other, Ops0, 4), 0);
307 cast<MachineSDNode>(Chain.getNode())->setMemRefs(MemRefs0, MemRefs0 + 1);
308
309 SDValue Ops1[] = { FPOdd, Offset1, Base, Chain };
310 Chain = SDValue(CurDAG->getMachineNode(Mips::SWC1, dl,
311 MVT::Other, Ops1, 4), 0);
312 cast<MachineSDNode>(Chain.getNode())->setMemRefs(MemRefs0, MemRefs0 + 1);
313
314 ReplaceUses(N.getValue(0), Chain);
315 return Chain.getNode();
316}
317
201/// Select instructions not customized! Used for
202/// expanded, promoted and normal instructions
203SDNode* MipsDAGToDAGISel::Select(SDValue N) {
204 SDNode *Node = N.getNode();
205 unsigned Opcode = Node->getOpcode();
206 DebugLoc dl = Node->getDebugLoc();
207
208 // Dump information about the Node being selected

--- 131 unchanged lines hidden (view full) ---

340 if (N.getValueType() == MVT::f64 && CN->isExactlyValue(+0.0)) {
341 SDValue Zero = CurDAG->getRegister(Mips::ZERO, MVT::i32);
342 ReplaceUses(N, Zero);
343 return Zero.getNode();
344 }
345 break;
346 }
347
318/// Select instructions not customized! Used for
319/// expanded, promoted and normal instructions
320SDNode* MipsDAGToDAGISel::Select(SDValue N) {
321 SDNode *Node = N.getNode();
322 unsigned Opcode = Node->getOpcode();
323 DebugLoc dl = Node->getDebugLoc();
324
325 // Dump information about the Node being selected

--- 131 unchanged lines hidden (view full) ---

457 if (N.getValueType() == MVT::f64 && CN->isExactlyValue(+0.0)) {
458 SDValue Zero = CurDAG->getRegister(Mips::ZERO, MVT::i32);
459 ReplaceUses(N, Zero);
460 return Zero.getNode();
461 }
462 break;
463 }
464
465 case ISD::LOAD:
466 if (SDNode *ResNode = SelectLoadFp64(N))
467 return ResNode;
468 // Other cases are autogenerated.
469 break;
470
471 case ISD::STORE:
472 if (SDNode *ResNode = SelectStoreFp64(N))
473 return ResNode;
474 // Other cases are autogenerated.
475 break;
476
348 /// Handle direct and indirect calls when using PIC. On PIC, when
349 /// GOT is smaller than about 64k (small code) the GA target is
350 /// loaded with only one instruction. Otherwise GA's target must
351 /// be loaded with 3 instructions.
352 case MipsISD::JmpLink: {
353 if (TM.getRelocationModel() == Reloc::PIC_) {
354 SDValue Chain = Node->getOperand(0);
355 SDValue Callee = Node->getOperand(1);

--- 52 unchanged lines hidden ---
477 /// Handle direct and indirect calls when using PIC. On PIC, when
478 /// GOT is smaller than about 64k (small code) the GA target is
479 /// loaded with only one instruction. Otherwise GA's target must
480 /// be loaded with 3 instructions.
481 case MipsISD::JmpLink: {
482 if (TM.getRelocationModel() == Reloc::PIC_) {
483 SDValue Chain = Node->getOperand(0);
484 SDValue Callee = Node->getOperand(1);

--- 52 unchanged lines hidden ---