ARMISelDAGToDAG.cpp revision ebdabda708348d54d86719a1af30e2410b5bcc0a
1//===-- ARMISelDAGToDAG.cpp - A dag to dag inst selector for ARM ----------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file was developed by Chris Lattner and is distributed under 6// the University of Illinois Open Source License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines an instruction selector for the ARM target. 11// 12//===----------------------------------------------------------------------===// 13 14#include "ARM.h" 15#include "ARMTargetMachine.h" 16#include "llvm/CallingConv.h" 17#include "llvm/DerivedTypes.h" 18#include "llvm/Function.h" 19#include "llvm/Constants.h" 20#include "llvm/Intrinsics.h" 21#include "llvm/CodeGen/MachineFrameInfo.h" 22#include "llvm/CodeGen/MachineFunction.h" 23#include "llvm/CodeGen/MachineInstrBuilder.h" 24#include "llvm/CodeGen/SelectionDAG.h" 25#include "llvm/CodeGen/SelectionDAGISel.h" 26#include "llvm/CodeGen/SSARegMap.h" 27#include "llvm/Target/TargetLowering.h" 28#include "llvm/Support/Debug.h" 29#include <iostream> 30#include <queue> 31#include <set> 32using namespace llvm; 33 34namespace { 35 class ARMTargetLowering : public TargetLowering { 36 int VarArgsFrameIndex; // FrameIndex for start of varargs area. 37 public: 38 ARMTargetLowering(TargetMachine &TM); 39 virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG); 40 virtual const char *getTargetNodeName(unsigned Opcode) const; 41 }; 42 43} 44 45ARMTargetLowering::ARMTargetLowering(TargetMachine &TM) 46 : TargetLowering(TM) { 47 addRegisterClass(MVT::i32, ARM::IntRegsRegisterClass); 48 49 //LLVM requires that a register class supports MVT::f64! 50 addRegisterClass(MVT::f64, ARM::IntRegsRegisterClass); 51 52 setOperationAction(ISD::RET, MVT::Other, Custom); 53 setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); 54 setOperationAction(ISD::ConstantPool, MVT::i32, Custom); 55 56 setOperationAction(ISD::SETCC, MVT::i32, Expand); 57 setOperationAction(ISD::SELECT_CC, MVT::i32, Custom); 58 setOperationAction(ISD::BR_CC, MVT::i32, Custom); 59 60 setOperationAction(ISD::VASTART, MVT::Other, Custom); 61 setOperationAction(ISD::VAEND, MVT::Other, Expand); 62 63 setSchedulingPreference(SchedulingForRegPressure); 64 computeRegisterProperties(); 65} 66 67namespace llvm { 68 namespace ARMISD { 69 enum NodeType { 70 // Start the numbering where the builting ops and target ops leave off. 71 FIRST_NUMBER = ISD::BUILTIN_OP_END+ARM::INSTRUCTION_LIST_END, 72 /// CALL - A direct function call. 73 CALL, 74 75 /// Return with a flag operand. 76 RET_FLAG, 77 78 CMP, 79 80 SELECT, 81 82 BR 83 }; 84 } 85} 86 87/// DAGCCToARMCC - Convert a DAG integer condition code to an ARM CC 88static ARMCC::CondCodes DAGCCToARMCC(ISD::CondCode CC) { 89 switch (CC) { 90 default: 91 std::cerr << "CC = " << CC << "\n"; 92 assert(0 && "Unknown condition code!"); 93 case ISD::SETUGT: return ARMCC::HI; 94 case ISD::SETULE: return ARMCC::LS; 95 case ISD::SETLE: return ARMCC::LE; 96 case ISD::SETLT: return ARMCC::LT; 97 case ISD::SETGT: return ARMCC::GT; 98 case ISD::SETNE: return ARMCC::NE; 99 case ISD::SETEQ: return ARMCC::EQ; 100 case ISD::SETGE: return ARMCC::GE; 101 case ISD::SETUGE: return ARMCC::CS; 102 case ISD::SETULT: return ARMCC::CC; 103 } 104} 105 106const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const { 107 switch (Opcode) { 108 default: return 0; 109 case ARMISD::CALL: return "ARMISD::CALL"; 110 case ARMISD::RET_FLAG: return "ARMISD::RET_FLAG"; 111 case ARMISD::SELECT: return "ARMISD::SELECT"; 112 case ARMISD::CMP: return "ARMISD::CMP"; 113 case ARMISD::BR: return "ARMISD::BR"; 114 } 115} 116 117// This transforms a ISD::CALL node into a 118// callseq_star <- ARMISD:CALL <- callseq_end 119// chain 120static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) { 121 SDOperand Chain = Op.getOperand(0); 122 unsigned CallConv = cast<ConstantSDNode>(Op.getOperand(1))->getValue(); 123 assert(CallConv == CallingConv::C && "unknown calling convention"); 124 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0; 125 bool isTailCall = cast<ConstantSDNode>(Op.getOperand(3))->getValue() != 0; 126 assert(isTailCall == false && "tail call not supported"); 127 SDOperand Callee = Op.getOperand(4); 128 unsigned NumOps = (Op.getNumOperands() - 5) / 2; 129 130 // Count how many bytes are to be pushed on the stack. 131 unsigned NumBytes = 0; 132 133 // Add up all the space actually used. 134 for (unsigned i = 4; i < NumOps; ++i) 135 NumBytes += MVT::getSizeInBits(Op.getOperand(5+2*i).getValueType())/8; 136 137 // Adjust the stack pointer for the new arguments... 138 // These operations are automatically eliminated by the prolog/epilog pass 139 Chain = DAG.getCALLSEQ_START(Chain, 140 DAG.getConstant(NumBytes, MVT::i32)); 141 142 SDOperand StackPtr = DAG.getRegister(ARM::R13, MVT::i32); 143 144 static const unsigned int num_regs = 4; 145 static const unsigned regs[num_regs] = { 146 ARM::R0, ARM::R1, ARM::R2, ARM::R3 147 }; 148 149 std::vector<std::pair<unsigned, SDOperand> > RegsToPass; 150 std::vector<SDOperand> MemOpChains; 151 152 for (unsigned i = 0; i != NumOps; ++i) { 153 SDOperand Arg = Op.getOperand(5+2*i); 154 assert(Arg.getValueType() == MVT::i32); 155 if (i < num_regs) 156 RegsToPass.push_back(std::make_pair(regs[i], Arg)); 157 else { 158 unsigned ArgOffset = (i - num_regs) * 4; 159 SDOperand PtrOff = DAG.getConstant(ArgOffset, StackPtr.getValueType()); 160 PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff); 161 MemOpChains.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, 162 Arg, PtrOff, DAG.getSrcValue(NULL))); 163 } 164 } 165 if (!MemOpChains.empty()) 166 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, 167 &MemOpChains[0], MemOpChains.size()); 168 169 // Build a sequence of copy-to-reg nodes chained together with token chain 170 // and flag operands which copy the outgoing args into the appropriate regs. 171 SDOperand InFlag; 172 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { 173 Chain = DAG.getCopyToReg(Chain, RegsToPass[i].first, RegsToPass[i].second, 174 InFlag); 175 InFlag = Chain.getValue(1); 176 } 177 178 std::vector<MVT::ValueType> NodeTys; 179 NodeTys.push_back(MVT::Other); // Returns a chain 180 NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use. 181 182 // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every 183 // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol 184 // node so that legalize doesn't hack it. 185 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) 186 Callee = DAG.getTargetGlobalAddress(G->getGlobal(), Callee.getValueType()); 187 188 // If this is a direct call, pass the chain and the callee. 189 assert (Callee.Val); 190 std::vector<SDOperand> Ops; 191 Ops.push_back(Chain); 192 Ops.push_back(Callee); 193 194 // Add argument registers to the end of the list so that they are known live 195 // into the call. 196 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) 197 Ops.push_back(DAG.getRegister(RegsToPass[i].first, 198 RegsToPass[i].second.getValueType())); 199 200 unsigned CallOpc = ARMISD::CALL; 201 if (InFlag.Val) 202 Ops.push_back(InFlag); 203 Chain = DAG.getNode(CallOpc, NodeTys, &Ops[0], Ops.size()); 204 InFlag = Chain.getValue(1); 205 206 std::vector<SDOperand> ResultVals; 207 NodeTys.clear(); 208 209 // If the call has results, copy the values out of the ret val registers. 210 switch (Op.Val->getValueType(0)) { 211 default: assert(0 && "Unexpected ret value!"); 212 case MVT::Other: 213 break; 214 case MVT::i32: 215 Chain = DAG.getCopyFromReg(Chain, ARM::R0, MVT::i32, InFlag).getValue(1); 216 ResultVals.push_back(Chain.getValue(0)); 217 NodeTys.push_back(MVT::i32); 218 } 219 220 Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, Chain, 221 DAG.getConstant(NumBytes, MVT::i32)); 222 NodeTys.push_back(MVT::Other); 223 224 if (ResultVals.empty()) 225 return Chain; 226 227 ResultVals.push_back(Chain); 228 SDOperand Res = DAG.getNode(ISD::MERGE_VALUES, NodeTys, &ResultVals[0], 229 ResultVals.size()); 230 return Res.getValue(Op.ResNo); 231} 232 233static SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG) { 234 SDOperand Copy; 235 SDOperand Chain = Op.getOperand(0); 236 switch(Op.getNumOperands()) { 237 default: 238 assert(0 && "Do not know how to return this many arguments!"); 239 abort(); 240 case 1: { 241 SDOperand LR = DAG.getRegister(ARM::R14, MVT::i32); 242 return DAG.getNode(ARMISD::RET_FLAG, MVT::Other, Chain); 243 } 244 case 3: 245 Copy = DAG.getCopyToReg(Chain, ARM::R0, Op.getOperand(1), SDOperand()); 246 if (DAG.getMachineFunction().liveout_empty()) 247 DAG.getMachineFunction().addLiveOut(ARM::R0); 248 break; 249 case 5: 250 Copy = DAG.getCopyToReg(Chain, ARM::R1, Op.getOperand(3), SDOperand()); 251 Copy = DAG.getCopyToReg(Copy, ARM::R0, Op.getOperand(1), Copy.getValue(1)); 252 // If we haven't noted the R0+R1 are live out, do so now. 253 if (DAG.getMachineFunction().liveout_empty()) { 254 DAG.getMachineFunction().addLiveOut(ARM::R0); 255 DAG.getMachineFunction().addLiveOut(ARM::R1); 256 } 257 break; 258 } 259 260 //We must use RET_FLAG instead of BRIND because BRIND doesn't have a flag 261 return DAG.getNode(ARMISD::RET_FLAG, MVT::Other, Copy, Copy.getValue(1)); 262} 263 264static SDOperand LowerFORMAL_ARGUMENT(SDOperand Op, SelectionDAG &DAG, 265 unsigned *vRegs, 266 unsigned ArgNo) { 267 MachineFunction &MF = DAG.getMachineFunction(); 268 MVT::ValueType ObjectVT = Op.getValue(ArgNo).getValueType(); 269 assert (ObjectVT == MVT::i32); 270 SDOperand Root = Op.getOperand(0); 271 SSARegMap *RegMap = MF.getSSARegMap(); 272 273 unsigned num_regs = 4; 274 static const unsigned REGS[] = { 275 ARM::R0, ARM::R1, ARM::R2, ARM::R3 276 }; 277 278 if(ArgNo < num_regs) { 279 unsigned VReg = RegMap->createVirtualRegister(&ARM::IntRegsRegClass); 280 MF.addLiveIn(REGS[ArgNo], VReg); 281 vRegs[ArgNo] = VReg; 282 return DAG.getCopyFromReg(Root, VReg, MVT::i32); 283 } else { 284 // If the argument is actually used, emit a load from the right stack 285 // slot. 286 if (!Op.Val->hasNUsesOfValue(0, ArgNo)) { 287 unsigned ArgOffset = (ArgNo - num_regs) * 4; 288 289 MachineFrameInfo *MFI = MF.getFrameInfo(); 290 unsigned ObjSize = MVT::getSizeInBits(ObjectVT)/8; 291 int FI = MFI->CreateFixedObject(ObjSize, ArgOffset); 292 SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32); 293 return DAG.getLoad(ObjectVT, Root, FIN, 294 DAG.getSrcValue(NULL)); 295 } else { 296 // Don't emit a dead load. 297 return DAG.getNode(ISD::UNDEF, ObjectVT); 298 } 299 } 300} 301 302static SDOperand LowerConstantPool(SDOperand Op, SelectionDAG &DAG) { 303 MVT::ValueType PtrVT = Op.getValueType(); 304 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op); 305 Constant *C = CP->getConstVal(); 306 SDOperand CPI = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment()); 307 308 return CPI; 309} 310 311static SDOperand LowerGlobalAddress(SDOperand Op, 312 SelectionDAG &DAG) { 313 GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); 314 int alignment = 2; 315 SDOperand CPAddr = DAG.getConstantPool(GV, MVT::i32, alignment); 316 return DAG.getLoad(MVT::i32, DAG.getEntryNode(), CPAddr, 317 DAG.getSrcValue(NULL)); 318} 319 320static SDOperand LowerVASTART(SDOperand Op, SelectionDAG &DAG, 321 unsigned VarArgsFrameIndex) { 322 // vastart just stores the address of the VarArgsFrameIndex slot into the 323 // memory location argument. 324 MVT::ValueType PtrVT = DAG.getTargetLoweringInfo().getPointerTy(); 325 SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, PtrVT); 326 return DAG.getNode(ISD::STORE, MVT::Other, Op.getOperand(0), FR, 327 Op.getOperand(1), Op.getOperand(2)); 328} 329 330static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG, 331 int &VarArgsFrameIndex) { 332 std::vector<SDOperand> ArgValues; 333 SDOperand Root = Op.getOperand(0); 334 unsigned VRegs[4]; 335 336 unsigned NumArgs = Op.Val->getNumValues()-1; 337 for (unsigned ArgNo = 0; ArgNo < NumArgs; ++ArgNo) { 338 SDOperand ArgVal = LowerFORMAL_ARGUMENT(Op, DAG, VRegs, ArgNo); 339 340 ArgValues.push_back(ArgVal); 341 } 342 343 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0; 344 if (isVarArg) { 345 MachineFunction &MF = DAG.getMachineFunction(); 346 SSARegMap *RegMap = MF.getSSARegMap(); 347 MachineFrameInfo *MFI = MF.getFrameInfo(); 348 VarArgsFrameIndex = MFI->CreateFixedObject(MVT::getSizeInBits(MVT::i32)/8, 349 -16 + NumArgs * 4); 350 351 352 static const unsigned REGS[] = { 353 ARM::R0, ARM::R1, ARM::R2, ARM::R3 354 }; 355 // If this function is vararg, store r0-r3 to their spots on the stack 356 // so that they may be loaded by deferencing the result of va_next. 357 SmallVector<SDOperand, 4> MemOps; 358 for (unsigned ArgNo = 0; ArgNo < 4; ++ArgNo) { 359 int ArgOffset = - (4 - ArgNo) * 4; 360 int FI = MFI->CreateFixedObject(MVT::getSizeInBits(MVT::i32)/8, 361 ArgOffset); 362 SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32); 363 364 unsigned VReg; 365 if (ArgNo < NumArgs) 366 VReg = VRegs[ArgNo]; 367 else 368 VReg = RegMap->createVirtualRegister(&ARM::IntRegsRegClass); 369 if (ArgNo >= NumArgs) 370 MF.addLiveIn(REGS[ArgNo], VReg); 371 372 SDOperand Val = DAG.getCopyFromReg(Root, VReg, MVT::i32); 373 SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1), 374 Val, FIN, DAG.getSrcValue(NULL)); 375 MemOps.push_back(Store); 376 } 377 Root = DAG.getNode(ISD::TokenFactor, MVT::Other,&MemOps[0],MemOps.size()); 378 } 379 380 ArgValues.push_back(Root); 381 382 // Return the new list of results. 383 std::vector<MVT::ValueType> RetVT(Op.Val->value_begin(), 384 Op.Val->value_end()); 385 return DAG.getNode(ISD::MERGE_VALUES, RetVT, &ArgValues[0], ArgValues.size()); 386} 387 388static SDOperand LowerSELECT_CC(SDOperand Op, SelectionDAG &DAG) { 389 SDOperand LHS = Op.getOperand(0); 390 SDOperand RHS = Op.getOperand(1); 391 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get(); 392 SDOperand TrueVal = Op.getOperand(2); 393 SDOperand FalseVal = Op.getOperand(3); 394 SDOperand ARMCC = DAG.getConstant(DAGCCToARMCC(CC), MVT::i32); 395 396 SDOperand Cmp = DAG.getNode(ARMISD::CMP, MVT::Flag, LHS, RHS); 397 return DAG.getNode(ARMISD::SELECT, MVT::i32, TrueVal, FalseVal, ARMCC, Cmp); 398} 399 400static SDOperand LowerBR_CC(SDOperand Op, SelectionDAG &DAG) { 401 SDOperand Chain = Op.getOperand(0); 402 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get(); 403 SDOperand LHS = Op.getOperand(2); 404 SDOperand RHS = Op.getOperand(3); 405 SDOperand Dest = Op.getOperand(4); 406 SDOperand ARMCC = DAG.getConstant(DAGCCToARMCC(CC), MVT::i32); 407 408 SDOperand Cmp = DAG.getNode(ARMISD::CMP, MVT::Flag, LHS, RHS); 409 return DAG.getNode(ARMISD::BR, MVT::Other, Chain, Dest, ARMCC, Cmp); 410} 411 412SDOperand ARMTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { 413 switch (Op.getOpcode()) { 414 default: 415 assert(0 && "Should not custom lower this!"); 416 abort(); 417 case ISD::ConstantPool: 418 return LowerConstantPool(Op, DAG); 419 case ISD::GlobalAddress: 420 return LowerGlobalAddress(Op, DAG); 421 case ISD::FORMAL_ARGUMENTS: 422 return LowerFORMAL_ARGUMENTS(Op, DAG, VarArgsFrameIndex); 423 case ISD::CALL: 424 return LowerCALL(Op, DAG); 425 case ISD::RET: 426 return LowerRET(Op, DAG); 427 case ISD::SELECT_CC: 428 return LowerSELECT_CC(Op, DAG); 429 case ISD::BR_CC: 430 return LowerBR_CC(Op, DAG); 431 case ISD::VASTART: 432 return LowerVASTART(Op, DAG, VarArgsFrameIndex); 433 } 434} 435 436//===----------------------------------------------------------------------===// 437// Instruction Selector Implementation 438//===----------------------------------------------------------------------===// 439 440//===--------------------------------------------------------------------===// 441/// ARMDAGToDAGISel - ARM specific code to select ARM machine 442/// instructions for SelectionDAG operations. 443/// 444namespace { 445class ARMDAGToDAGISel : public SelectionDAGISel { 446 ARMTargetLowering Lowering; 447 448public: 449 ARMDAGToDAGISel(TargetMachine &TM) 450 : SelectionDAGISel(Lowering), Lowering(TM) { 451 } 452 453 SDNode *Select(SDOperand Op); 454 virtual void InstructionSelectBasicBlock(SelectionDAG &DAG); 455 bool SelectAddrRegImm(SDOperand N, SDOperand &Offset, SDOperand &Base); 456 bool SelectAddrMode1(SDOperand N, SDOperand &Arg, SDOperand &Shift, 457 SDOperand &ShiftType); 458 459 // Include the pieces autogenerated from the target description. 460#include "ARMGenDAGISel.inc" 461}; 462 463void ARMDAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) { 464 DEBUG(BB->dump()); 465 466 DAG.setRoot(SelectRoot(DAG.getRoot())); 467 DAG.RemoveDeadNodes(); 468 469 ScheduleAndEmitDAG(DAG); 470} 471 472static bool isInt12Immediate(SDNode *N, short &Imm) { 473 if (N->getOpcode() != ISD::Constant) 474 return false; 475 476 int32_t t = cast<ConstantSDNode>(N)->getValue(); 477 int max = 1<<12; 478 int min = -max; 479 if (t > min && t < max) { 480 Imm = t; 481 return true; 482 } 483 else 484 return false; 485} 486 487static bool isInt12Immediate(SDOperand Op, short &Imm) { 488 return isInt12Immediate(Op.Val, Imm); 489} 490 491static uint32_t rotateL(uint32_t x) { 492 uint32_t bit31 = (x & (1 << 31)) >> 31; 493 uint32_t t = x << 1; 494 return t | bit31; 495} 496 497static bool isUInt8Immediate(uint32_t x) { 498 return x < (1 << 8); 499} 500 501static bool isRotInt8Immediate(uint32_t x) { 502 int r; 503 for (r = 0; r < 16; r++) { 504 if (isUInt8Immediate(x)) 505 return true; 506 x = rotateL(rotateL(x)); 507 } 508 return false; 509} 510 511bool ARMDAGToDAGISel::SelectAddrMode1(SDOperand N, 512 SDOperand &Arg, 513 SDOperand &Shift, 514 SDOperand &ShiftType) { 515 switch(N.getOpcode()) { 516 case ISD::Constant: { 517 uint32_t val = cast<ConstantSDNode>(N)->getValue(); 518 if(!isRotInt8Immediate(val)) { 519 const Type *t = MVT::getTypeForValueType(MVT::i32); 520 Constant *C = ConstantUInt::get(t, val); 521 int alignment = 2; 522 SDOperand Addr = CurDAG->getTargetConstantPool(C, MVT::i32, alignment); 523 SDOperand Z = CurDAG->getTargetConstant(0, MVT::i32); 524 SDNode *n = CurDAG->getTargetNode(ARM::ldr, MVT::i32, Z, Addr); 525 Arg = SDOperand(n, 0); 526 } else 527 Arg = CurDAG->getTargetConstant(val, MVT::i32); 528 529 Shift = CurDAG->getTargetConstant(0, MVT::i32); 530 ShiftType = CurDAG->getTargetConstant(ARMShift::LSL, MVT::i32); 531 return true; 532 } 533 case ISD::SRA: 534 Arg = N.getOperand(0); 535 Shift = N.getOperand(1); 536 ShiftType = CurDAG->getTargetConstant(ARMShift::ASR, MVT::i32); 537 return true; 538 case ISD::SRL: 539 Arg = N.getOperand(0); 540 Shift = N.getOperand(1); 541 ShiftType = CurDAG->getTargetConstant(ARMShift::LSR, MVT::i32); 542 return true; 543 case ISD::SHL: 544 Arg = N.getOperand(0); 545 Shift = N.getOperand(1); 546 ShiftType = CurDAG->getTargetConstant(ARMShift::LSL, MVT::i32); 547 return true; 548 } 549 550 Arg = N; 551 Shift = CurDAG->getTargetConstant(0, MVT::i32); 552 ShiftType = CurDAG->getTargetConstant(ARMShift::LSL, MVT::i32); 553 return true; 554} 555 556//register plus/minus 12 bit offset 557bool ARMDAGToDAGISel::SelectAddrRegImm(SDOperand N, SDOperand &Offset, 558 SDOperand &Base) { 559 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(N)) { 560 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 561 Offset = CurDAG->getTargetConstant(0, MVT::i32); 562 return true; 563 } 564 if (N.getOpcode() == ISD::ADD) { 565 short imm = 0; 566 if (isInt12Immediate(N.getOperand(1), imm)) { 567 Offset = CurDAG->getTargetConstant(imm, MVT::i32); 568 if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N.getOperand(0))) { 569 Base = CurDAG->getTargetFrameIndex(FI->getIndex(), N.getValueType()); 570 } else { 571 Base = N.getOperand(0); 572 } 573 return true; // [r+i] 574 } 575 } 576 577 Offset = CurDAG->getTargetConstant(0, MVT::i32); 578 if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N)) { 579 Base = CurDAG->getTargetFrameIndex(FI->getIndex(), N.getValueType()); 580 } 581 else 582 Base = N; 583 return true; //any address fits in a register 584} 585 586SDNode *ARMDAGToDAGISel::Select(SDOperand Op) { 587 SDNode *N = Op.Val; 588 589 switch (N->getOpcode()) { 590 default: 591 return SelectCode(Op); 592 break; 593 } 594 return NULL; 595} 596 597} // end anonymous namespace 598 599/// createARMISelDag - This pass converts a legalized DAG into a 600/// ARM-specific DAG, ready for instruction scheduling. 601/// 602FunctionPass *llvm::createARMISelDag(TargetMachine &TM) { 603 return new ARMDAGToDAGISel(TM); 604} 605