PPCISelDAGToDAG.cpp revision 222adac30a642b5ea4a916eb3e97d8d95eb32bea
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===-- PPC32ISelDAGToDAG.cpp - PPC32 pattern matching inst selector ------===// 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The LLVM Compiler Infrastructure 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file was developed by Chris Lattner and is distributed under 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the University of Illinois Open Source License. See LICENSE.TXT for details. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file defines a pattern matching instruction selector for 32 bit PowerPC, 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// converting from a legalized dag to a PPC dag. 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 139ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch//===----------------------------------------------------------------------===// 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "PowerPC.h" 16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "PPC32TargetMachine.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "PPC32ISelLowering.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/CodeGen/MachineInstrBuilder.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/CodeGen/MachineFunction.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/CodeGen/SSARegMap.h" 217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "llvm/CodeGen/SelectionDAG.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/CodeGen/SelectionDAGISel.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Target/TargetOptions.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/ADT/Statistic.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Constants.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/GlobalValue.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Support/Debug.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Support/MathExtras.h" 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)using namespace llvm; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Statistic<> FusedFP ("ppc-codegen", "Number of fused fp operations"); 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Statistic<> FrameOff("ppc-codegen", "Number of frame idx offsets collapsed"); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) //===--------------------------------------------------------------------===// 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// PPC32DAGToDAGISel - PPC32 specific code to select PPC32 machine 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// instructions for SelectionDAG operations. 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class PPC32DAGToDAGISel : public SelectionDAGISel { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PPC32TargetLowering PPC32Lowering; 41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) unsigned GlobalBaseReg; 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PPC32DAGToDAGISel(TargetMachine &TM) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : SelectionDAGISel(PPC32Lowering), PPC32Lowering(TM) {} 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool runOnFunction(Function &Fn) { 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Make sure we re-emit a set of the global base reg if necessary 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GlobalBaseReg = 0; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SelectionDAGISel::runOnFunction(Fn); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// getI32Imm - Return a target constant with the specified value, of type 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// i32. 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) inline SDOperand getI32Imm(unsigned Imm) { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CurDAG->getTargetConstant(Imm, MVT::i32); 565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// getGlobalBaseReg - insert code into the entry mbb to materialize the PIC 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// base register. Return the virtual register that holds this value. 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDOperand getGlobalBaseReg(); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Select - Convert the specified operand from a target-independent to a 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // target-specific node if it hasn't already been changed. 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand Select(SDOperand Op); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDNode *SelectIntImmediateExpr(SDOperand LHS, SDOperand RHS, 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned OCHi, unsigned OCLo, 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool IsArithmetic = false, 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Negate = false); 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDNode *SelectBitfieldInsert(SDNode *N); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// SelectCC - Select a comparison of the specified values with the 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// specified condition code, returning the CR# of the expression. 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand SelectCC(SDOperand LHS, SDOperand RHS, ISD::CondCode CC); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// SelectAddr - Given the specified address, return the two operands for a 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// load/store instruction, and return true if it should be an indexed [r+r] 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// operation. 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool SelectAddr(SDOperand Addr, SDOperand &Op1, SDOperand &Op2); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand BuildSDIVSequence(SDNode *N); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand BuildUDIVSequence(SDNode *N); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// InstructionSelectBasicBlock - This callback is invoked by 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void InstructionSelectBasicBlock(SelectionDAG &DAG); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual const char *getPassName() const { 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return "PowerPC DAG->DAG Pattern Instruction Selection"; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Include the pieces autogenerated from the target description. 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "PPC32GenDAGISel.inc" 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)private: 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand SelectDYNAMIC_STACKALLOC(SDOperand Op); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand SelectADD_PARTS(SDOperand Op); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand SelectSUB_PARTS(SDOperand Op); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand SelectSETCC(SDOperand Op); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// InstructionSelectBasicBlock - This callback is invoked by 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// SelectionDAGISel when it has created a SelectionDAG for us to codegen. 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PPC32DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DEBUG(BB->dump()); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The selection process is inherently a bottom-up recursive process (users 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // select their uses before themselves). Given infinite stack space, we 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // could just start selecting on the root and traverse the whole graph. In 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // practice however, this causes us to run out of stack space on large basic 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // blocks. To avoid this problem, select the entry node, then all its uses, 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // iteratively instead of recursively. 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<SDOperand> Worklist; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Worklist.push_back(DAG.getEntryNode()); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note that we can do this in the PPC target (scanning forward across token 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // chain edges) because no nodes ever get folded across these edges. On a 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // target like X86 which supports load/modify/store operations, this would 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // have to be more careful. 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (!Worklist.empty()) { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand Node = Worklist.back(); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Worklist.pop_back(); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((Node.Val->getOpcode() >= ISD::BUILTIN_OP_END && 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Node.Val->getOpcode() < PPCISD::FIRST_NUMBER) || 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CodeGenMap.count(Node)) continue; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (SDNode::use_iterator UI = Node.Val->use_begin(), 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) E = Node.Val->use_end(); UI != E; ++UI) { 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Scan the values. If this use has a value that is a token chain, add it 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to the worklist. 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDNode *User = *UI; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned i = 0, e = User->getNumValues(); i != e; ++i) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (User->getValueType(i) == MVT::Other) { 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Worklist.push_back(SDOperand(User, i)); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Finally, legalize this node. 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Select(Node); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Select target instructions for the DAG. 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DAG.setRoot(Select(DAG.getRoot())); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CodeGenMap.clear(); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DAG.RemoveDeadNodes(); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Emit machine code to BB. 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScheduleAndEmitDAG(DAG); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// getGlobalBaseReg - Output the instructions required to put the 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// base address to use for accessing globals into a register. 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SDOperand PPC32DAGToDAGISel::getGlobalBaseReg() { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GlobalBaseReg) { 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Insert the set of GlobalBaseReg into the first MBB of the function 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MachineBasicBlock &FirstMBB = BB->getParent()->front(); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MachineBasicBlock::iterator MBBI = FirstMBB.begin(); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSARegMap *RegMap = BB->getParent()->getSSARegMap(); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GlobalBaseReg = RegMap->createVirtualRegister(PPC32::GPRCRegisterClass); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BuildMI(FirstMBB, MBBI, PPC::MovePCtoLR, 0, PPC::LR); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BuildMI(FirstMBB, MBBI, PPC::MFLR, 1, GlobalBaseReg); 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CurDAG->getRegister(GlobalBaseReg, MVT::i32); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// isIntImmediate - This method tests to see if a constant operand. 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If so Imm will receive the 32 bit value. 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool isIntImmediate(SDNode *N, unsigned& Imm) { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (N->getOpcode() == ISD::Constant) { 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Imm = cast<ConstantSDNode>(N)->getValue(); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// isOprShiftImm - Returns true if the specified operand is a shift opcode with 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a immediate shift count less than 32. 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool isOprShiftImm(SDNode *N, unsigned& Opc, unsigned& SH) { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Opc = N->getOpcode(); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (Opc == ISD::SHL || Opc == ISD::SRL || Opc == ISD::SRA) && 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) isIntImmediate(N->getOperand(1).Val, SH) && SH < 32; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// isRunOfOnes - Returns true iff Val consists of one contiguous run of 1s with 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// any number of 0s on either side. The 1s are allowed to wrap from LSB to 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// MSB, so 0x000FFF0, 0x0000FFFF, and 0xFF0000FF are all runs. 0x0F0F0000 is 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// not, since all 1s are not contiguous. 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool isRunOfOnes(unsigned Val, unsigned &MB, unsigned &ME) { 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (isShiftedMask_32(Val)) { 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // look for the first non-zero bit 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MB = CountLeadingZeros_32(Val); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // look for the first zero bit after the run of ones 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ME = CountLeadingZeros_32((Val - 1) ^ Val); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Val = ~Val; // invert mask 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (isShiftedMask_32(Val)) { 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // effectively look for the first zero bit 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ME = CountLeadingZeros_32(Val) - 1; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // effectively look for the first one bit after the run of zeros 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MB = CountLeadingZeros_32((Val - 1) ^ Val) + 1; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // no run present 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// isRotateAndMask - Returns true if Mask and Shift can be folded in to a rotate 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// and mask opcode and mask operation. 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool isRotateAndMask(SDNode *N, unsigned Mask, bool IsShiftMask, 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned &SH, unsigned &MB, unsigned &ME) { 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned Shift = 32; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned Indeterminant = ~0; // bit mask marking indeterminant results 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned Opcode = N->getOpcode(); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (N->getNumOperands() != 2 || 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !isIntImmediate(N->getOperand(1).Val, Shift) || (Shift > 31)) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Opcode == ISD::SHL) { 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // apply shift left to mask if it comes first 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsShiftMask) Mask = Mask << Shift; 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // determine which bits are made indeterminant by shift 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Indeterminant = ~(0xFFFFFFFFu << Shift); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (Opcode == ISD::SRA || Opcode == ISD::SRL) { 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // apply shift right to mask if it comes first 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsShiftMask) Mask = Mask >> Shift; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // determine which bits are made indeterminant by shift 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Indeterminant = ~(0xFFFFFFFFu >> Shift); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // adjust for the left rotate 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Shift = 32 - Shift; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // if the mask doesn't intersect any Indeterminant bits 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Mask && !(Mask & Indeterminant)) { 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SH = Shift; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // make sure the mask is still a mask (wrap arounds may not be) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return isRunOfOnes(Mask, MB, ME); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// isOpcWithIntImmediate - This method tests to see if the node is a specific 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// opcode and that it has a immediate integer right operand. 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If so Imm will receive the 32 bit value. 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool isOpcWithIntImmediate(SDNode *N, unsigned Opc, unsigned& Imm) { 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return N->getOpcode() == Opc && isIntImmediate(N->getOperand(1).Val, Imm); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// isOprNot - Returns true if the specified operand is an xor with immediate -1. 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool isOprNot(SDNode *N) { 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned Imm; 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return isOpcWithIntImmediate(N, ISD::XOR, Imm) && (signed)Imm == -1; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Immediate constant composers. 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Lo16 - grabs the lo 16 bits from a 32 bit constant. 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Hi16 - grabs the hi 16 bits from a 32 bit constant. 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HA16 - computes the hi bits required if the lo bits are add/subtracted in 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// arithmethically. 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static unsigned Lo16(unsigned x) { return x & 0x0000FFFF; } 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static unsigned Hi16(unsigned x) { return Lo16(x >> 16); } 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static unsigned HA16(unsigned x) { return Hi16((signed)x - (signed short)x); } 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// isIntImmediate - This method tests to see if a constant operand. 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If so Imm will receive the 32 bit value. 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static bool isIntImmediate(SDOperand N, unsigned& Imm) { 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N)) { 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Imm = (unsigned)CN->getSignExtended(); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// SelectBitfieldInsert - turn an or of two masked values into 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// the rotate left word immediate then mask insert (rlwimi) instruction. 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// Returns true on success, false if the caller still needs to select OR. 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// Patterns matched: 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// 1. or shl, and 5. or and, and 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// 2. or and, shl 6. or shl, shr 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// 3. or shr, and 7. or shr, shl 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// 4. or and, shr 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SDNode *PPC32DAGToDAGISel::SelectBitfieldInsert(SDNode *N) { 29290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) bool IsRotate = false; 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned TgtMask = 0xFFFFFFFF, InsMask = 0xFFFFFFFF, SH = 0; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned Value; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand Op0 = N->getOperand(0); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand Op1 = N->getOperand(1); 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned Op0Opc = Op0.getOpcode(); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned Op1Opc = Op1.getOpcode(); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that we have the correct opcodes 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ISD::SHL != Op0Opc && ISD::SRL != Op0Opc && ISD::AND != Op0Opc) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ISD::SHL != Op1Opc && ISD::SRL != Op1Opc && ISD::AND != Op1Opc) 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Generate Mask value for Target 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (isIntImmediate(Op0.getOperand(1), Value)) { 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch(Op0Opc) { 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::SHL: TgtMask <<= Value; break; 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::SRL: TgtMask >>= Value; break; 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::AND: TgtMask &= Value; break; 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Generate Mask value for Insert 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!isIntImmediate(Op1.getOperand(1), Value)) 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch(Op1Opc) { 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::SHL: 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SH = Value; 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InsMask <<= SH; 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Op0Opc == ISD::SRL) IsRotate = true; 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::SRL: 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SH = Value; 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InsMask >>= SH; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SH = 32-SH; 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Op0Opc == ISD::SHL) IsRotate = true; 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::AND: 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InsMask &= Value; 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If both of the inputs are ANDs and one of them has a logical shift by 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // constant as its input, make that AND the inserted value so that we can 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // combine the shift into the rotate part of the rlwimi instruction 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool IsAndWithShiftOp = false; 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Op0Opc == ISD::AND && Op1Opc == ISD::AND) { 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Op1.getOperand(0).getOpcode() == ISD::SHL || 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Op1.getOperand(0).getOpcode() == ISD::SRL) { 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (isIntImmediate(Op1.getOperand(0).getOperand(1), Value)) { 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SH = Op1.getOperand(0).getOpcode() == ISD::SHL ? Value : 32 - Value; 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IsAndWithShiftOp = true; 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (Op0.getOperand(0).getOpcode() == ISD::SHL || 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Op0.getOperand(0).getOpcode() == ISD::SRL) { 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (isIntImmediate(Op0.getOperand(0).getOperand(1), Value)) { 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::swap(Op0, Op1); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::swap(TgtMask, InsMask); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SH = Op1.getOperand(0).getOpcode() == ISD::SHL ? Value : 32 - Value; 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IsAndWithShiftOp = true; 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that the Target mask and Insert mask together form a full word mask 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and that the Insert mask is a run of set bits (which implies both are runs 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // of set bits). Given that, Select the arguments and generate the rlwimi 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // instruction. 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned MB, ME; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (((TgtMask & InsMask) == 0) && isRunOfOnes(InsMask, MB, ME)) { 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool fullMask = (TgtMask ^ InsMask) == 0xFFFFFFFF; 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Op0IsAND = Op0Opc == ISD::AND; 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check for rotlwi / rotrwi here, a special case of bitfield insert 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // where both bitfield halves are sourced from the same value. 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsRotate && fullMask && 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) N->getOperand(0).getOperand(0) == N->getOperand(1).getOperand(0)) { 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Op0 = CurDAG->getTargetNode(PPC::RLWINM, MVT::i32, 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Select(N->getOperand(0).getOperand(0)), 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getI32Imm(SH), getI32Imm(0), getI32Imm(31)); 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Op0.Val; 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand Tmp1 = (Op0IsAND && fullMask) ? Select(Op0.getOperand(0)) 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Select(Op0); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand Tmp2 = IsAndWithShiftOp ? Select(Op1.getOperand(0).getOperand(0)) 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : Select(Op1.getOperand(0)); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Op0 = CurDAG->getTargetNode(PPC::RLWIMI, MVT::i32, Tmp1, Tmp2, 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getI32Imm(SH), getI32Imm(MB), getI32Imm(ME)); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Op0.Val; 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SelectIntImmediateExpr - Choose code for integer operations with an immediate 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// operand. 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SDNode *PPC32DAGToDAGISel::SelectIntImmediateExpr(SDOperand LHS, SDOperand RHS, 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned OCHi, unsigned OCLo, 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool IsArithmetic, 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Negate) { 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check to make sure this is a constant. 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConstantSDNode *CN = dyn_cast<ConstantSDNode>(RHS); 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Exit if not a constant. 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!CN) return 0; 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Extract immediate. 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned C = (unsigned)CN->getValue(); 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Negate if required (ISD::SUB). 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Negate) C = -C; 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the hi and lo portions of constant. 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned Hi = IsArithmetic ? HA16(C) : Hi16(C); 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned Lo = Lo16(C); 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If two instructions are needed and usage indicates it would be better to 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // load immediate into a register, bail out. 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Hi && Lo && CN->use_size() > 2) return false; 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Select the first operand. 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand Opr0 = Select(LHS); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Lo) // Add in the lo-part. 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Opr0 = CurDAG->getTargetNode(OCLo, MVT::i32, Opr0, getI32Imm(Lo)); 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Hi) // Add in the hi-part. 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Opr0 = CurDAG->getTargetNode(OCHi, MVT::i32, Opr0, getI32Imm(Hi)); 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Opr0.Val; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// SelectAddr - Given the specified address, return the two operands for a 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// load/store instruction, and return true if it should be an indexed [r+r] 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// operation. 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PPC32DAGToDAGISel::SelectAddr(SDOperand Addr, SDOperand &Op1, 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand &Op2) { 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned imm = 0; 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Addr.getOpcode() == ISD::ADD) { 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (isIntImmediate(Addr.getOperand(1), imm) && isInt16(imm)) { 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Op1 = getI32Imm(Lo16(imm)); 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (FrameIndexSDNode *FI = 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) { 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++FrameOff; 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Op2 = CurDAG->getTargetFrameIndex(FI->getIndex(), MVT::i32); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Op2 = Select(Addr.getOperand(0)); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Op1 = Select(Addr.getOperand(0)); 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Op2 = Select(Addr.getOperand(1)); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; // [r+r] 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now check if we're dealing with a global, and whether or not we should emit 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // an optimized load or store for statics. 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GlobalAddressSDNode *GN = dyn_cast<GlobalAddressSDNode>(Addr)) { 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GlobalValue *GV = GN->getGlobal(); 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GV->hasWeakLinkage() && !GV->isExternal()) { 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Op1 = CurDAG->getTargetGlobalAddress(GV, MVT::i32); 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (PICEnabled) 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Op2 = CurDAG->getTargetNode(PPC::ADDIS, MVT::i32, getGlobalBaseReg(), 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Op1); 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Op2 = CurDAG->getTargetNode(PPC::LIS, MVT::i32, Op1); 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Addr)) { 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Op1 = getI32Imm(0); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Op2 = CurDAG->getTargetFrameIndex(FI->getIndex(), MVT::i32); 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Addr)) { 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Op1 = Addr; 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (PICEnabled) 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Op2 = CurDAG->getTargetNode(PPC::ADDIS, MVT::i32, getGlobalBaseReg(),Op1); 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Op2 = CurDAG->getTargetNode(PPC::LIS, MVT::i32, Op1); 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Op1 = getI32Imm(0); 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Op2 = Select(Addr); 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// SelectCC - Select a comparison of the specified values with the specified 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// condition code, returning the CR# of the expression. 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SDOperand PPC32DAGToDAGISel::SelectCC(SDOperand LHS, SDOperand RHS, 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ISD::CondCode CC) { 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Always select the LHS. 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LHS = Select(LHS); 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use U to determine whether the SETCC immediate range is signed or not. 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (MVT::isInteger(LHS.getValueType())) { 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool U = ISD::isUnsignedIntSetCC(CC); 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned Imm; 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (isIntImmediate(RHS, Imm) && 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((U && isUInt16(Imm)) || (!U && isInt16(Imm)))) 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CurDAG->getTargetNode(U ? PPC::CMPLWI : PPC::CMPWI, MVT::i32, 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LHS, getI32Imm(Lo16(Imm))); 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CurDAG->getTargetNode(U ? PPC::CMPLW : PPC::CMPW, MVT::i32, 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LHS, Select(RHS)); 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (LHS.getValueType() == MVT::f32) { 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CurDAG->getTargetNode(PPC::FCMPUS, MVT::i32, LHS, Select(RHS)); 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CurDAG->getTargetNode(PPC::FCMPUD, MVT::i32, LHS, Select(RHS)); 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// getBCCForSetCC - Returns the PowerPC condition branch mnemonic corresponding 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// to Condition. 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static unsigned getBCCForSetCC(ISD::CondCode CC) { 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (CC) { 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: assert(0 && "Unknown condition!"); abort(); 5052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ISD::SETEQ: return PPC::BEQ; 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::SETNE: return PPC::BNE; 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::SETULT: 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::SETLT: return PPC::BLT; 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::SETULE: 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::SETLE: return PPC::BLE; 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ISD::SETUGT: 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::SETGT: return PPC::BGT; 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::SETUGE: 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::SETGE: return PPC::BGE; 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// getCRIdxForSetCC - Return the index of the condition register field 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// associated with the SetCC condition, and whether or not the field is 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// treated as inverted. That is, lt = 0; ge = 0 inverted. 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static unsigned getCRIdxForSetCC(ISD::CondCode CC, bool& Inv) { 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (CC) { 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: assert(0 && "Unknown condition!"); abort(); 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::SETULT: 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::SETLT: Inv = false; return 0; 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::SETUGE: 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::SETGE: Inv = true; return 0; 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::SETUGT: 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::SETGT: Inv = false; return 1; 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::SETULE: 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::SETLE: Inv = true; return 1; 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::SETEQ: Inv = false; return 2; 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::SETNE: Inv = true; return 2; 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Structure used to return the necessary information to codegen an SDIV as 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a multiply. 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ms { 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int m; // magic number 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int s; // shift amount 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct mu { 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int m; // magic number 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int a; // add indicator 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int s; // shift amount 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// magic - calculate the magic numbers required to codegen an integer sdiv as 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// a sequence of multiply and shifts. Requires that the divisor not be 0, 1, 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// or -1. 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static struct ms magic(int d) { 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int p; 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int ad, anc, delta, q1, r1, q2, r2, t; 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const unsigned int two31 = 0x80000000U; 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct ms mag; 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ad = abs(d); 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = two31 + ((unsigned int)d >> 31); 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) anc = t - 1 - t%ad; // absolute value of nc 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p = 31; // initialize p 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) q1 = two31/anc; // initialize q1 = 2p/abs(nc) 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) r1 = two31 - q1*anc; // initialize r1 = rem(2p,abs(nc)) 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) q2 = two31/ad; // initialize q2 = 2p/abs(d) 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) r2 = two31 - q2*ad; // initialize r2 = rem(2p,abs(d)) 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p = p + 1; 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) q1 = 2*q1; // update q1 = 2p/abs(nc) 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) r1 = 2*r1; // update r1 = rem(2p/abs(nc)) 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (r1 >= anc) { // must be unsigned comparison 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) q1 = q1 + 1; 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) r1 = r1 - anc; 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) q2 = 2*q2; // update q2 = 2p/abs(d) 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) r2 = 2*r2; // update r2 = rem(2p/abs(d)) 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (r2 >= ad) { // must be unsigned comparison 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) q2 = q2 + 1; 58190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) r2 = r2 - ad; 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delta = ad - r2; 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (q1 < delta || (q1 == delta && r1 == 0)); 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mag.m = q2 + 1; 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (d < 0) mag.m = -mag.m; // resulting magic number 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mag.s = p - 32; // resulting shift 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return mag; 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// magicu - calculate the magic numbers required to codegen an integer udiv as 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// a sequence of multiply, add and shifts. Requires that the divisor not be 0. 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static struct mu magicu(unsigned d) 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int p; 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int nc, delta, q1, r1, q2, r2; 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct mu magu; 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) magu.a = 0; // initialize "add" indicator 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nc = - 1 - (-d)%d; 6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) p = 31; // initialize p 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) q1 = 0x80000000/nc; // initialize q1 = 2p/nc 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) r1 = 0x80000000 - q1*nc; // initialize r1 = rem(2p,nc) 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) q2 = 0x7FFFFFFF/d; // initialize q2 = (2p-1)/d 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) r2 = 0x7FFFFFFF - q2*d; // initialize r2 = rem((2p-1),d) 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p = p + 1; 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (r1 >= nc - r1 ) { 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) q1 = 2*q1 + 1; // update q1 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) r1 = 2*r1 - nc; // update r1 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) q1 = 2*q1; // update q1 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) r1 = 2*r1; // update r1 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (r2 + 1 >= d - r2) { 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (q2 >= 0x7FFFFFFF) magu.a = 1; 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) q2 = 2*q2 + 1; // update q2 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) r2 = 2*r2 + 1 - d; // update r2 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (q2 >= 0x80000000) magu.a = 1; 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) q2 = 2*q2; // update q2 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) r2 = 2*r2 + 1; // update r2 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delta = d - 1 - r2; 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (p < 64 && (q1 < delta || (q1 == delta && r1 == 0))); 6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) magu.m = q2 + 1; // resulting magic number 6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) magu.s = p - 32; // resulting shift 6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return magu; 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// BuildSDIVSequence - Given an ISD::SDIV node expressing a divide by constant, 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// return a DAG expression to select that will generate the same value by 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// multiplying by a magic number. See: 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// <http://the.wall.riscom.net/books/proc/ppc/cwg/code2.html> 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SDOperand PPC32DAGToDAGISel::BuildSDIVSequence(SDNode *N) { 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int d = (int)cast<ConstantSDNode>(N->getOperand(1))->getValue(); 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ms magics = magic(d); 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Multiply the numerator (operand 0) by the magic value 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand Q = CurDAG->getNode(ISD::MULHS, MVT::i32, N->getOperand(0), 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->getConstant(magics.m, MVT::i32)); 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If d > 0 and m < 0, add the numerator 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (d > 0 && magics.m < 0) 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Q = CurDAG->getNode(ISD::ADD, MVT::i32, Q, N->getOperand(0)); 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If d < 0 and m > 0, subtract the numerator. 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (d < 0 && magics.m > 0) 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Q = CurDAG->getNode(ISD::SUB, MVT::i32, Q, N->getOperand(0)); 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Shift right algebraic if shift value is nonzero 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (magics.s > 0) 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Q = CurDAG->getNode(ISD::SRA, MVT::i32, Q, 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->getConstant(magics.s, MVT::i32)); 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Extract the sign bit and add it to the quotient 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand T = 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->getNode(ISD::SRL, MVT::i32, Q, CurDAG->getConstant(31, MVT::i32)); 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CurDAG->getNode(ISD::ADD, MVT::i32, Q, T); 6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// BuildUDIVSequence - Given an ISD::UDIV node expressing a divide by constant, 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// return a DAG expression to select that will generate the same value by 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// multiplying by a magic number. See: 6625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)/// <http://the.wall.riscom.net/books/proc/ppc/cwg/code2.html> 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SDOperand PPC32DAGToDAGISel::BuildUDIVSequence(SDNode *N) { 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned d = (unsigned)cast<ConstantSDNode>(N->getOperand(1))->getValue(); 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mu magics = magicu(d); 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Multiply the numerator (operand 0) by the magic value 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand Q = CurDAG->getNode(ISD::MULHU, MVT::i32, N->getOperand(0), 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->getConstant(magics.m, MVT::i32)); 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (magics.a == 0) { 67090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return CurDAG->getNode(ISD::SRL, MVT::i32, Q, 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->getConstant(magics.s, MVT::i32)); 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand NPQ = CurDAG->getNode(ISD::SUB, MVT::i32, N->getOperand(0), Q); 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPQ = CurDAG->getNode(ISD::SRL, MVT::i32, NPQ, 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->getConstant(1, MVT::i32)); 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NPQ = CurDAG->getNode(ISD::ADD, MVT::i32, NPQ, Q); 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CurDAG->getNode(ISD::SRL, MVT::i32, NPQ, 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->getConstant(magics.s-1, MVT::i32)); 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SDOperand PPC32DAGToDAGISel::SelectDYNAMIC_STACKALLOC(SDOperand Op) { 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDNode *N = Op.Val; 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // FIXME: We are currently ignoring the requested alignment for handling 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // greater than the stack alignment. This will need to be revisited at some 6875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // point. Align = N.getOperand(2); 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!isa<ConstantSDNode>(N->getOperand(2)) || 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cast<ConstantSDNode>(N->getOperand(2))->getValue() != 0) { 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::cerr << "Cannot allocate stack object with greater alignment than" 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " the stack alignment yet!"; 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) abort(); 6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDOperand Chain = Select(N->getOperand(0)); 6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDOperand Amt = Select(N->getOperand(1)); 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand R1Reg = CurDAG->getRegister(PPC::R1, MVT::i32); 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand R1Val = CurDAG->getCopyFromReg(Chain, PPC::R1, MVT::i32); 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Chain = R1Val.getValue(1); 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Subtract the amount (guaranteed to be a multiple of the stack alignment) 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // from the stack pointer, giving us the result pointer. 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand Result = CurDAG->getTargetNode(PPC::SUBF, MVT::i32, Amt, R1Val); 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Copy this result back into R1. 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Chain = CurDAG->getNode(ISD::CopyToReg, MVT::Other, Chain, R1Reg, Result); 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Copy this result back out of R1 to make sure we're not using the stack 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // space without decrementing the stack pointer. 7115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu Result = CurDAG->getCopyFromReg(Chain, PPC::R1, MVT::i32); 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Finally, replace the DYNAMIC_STACKALLOC with the copyfromreg. 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CodeGenMap[Op.getValue(0)] = Result; 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CodeGenMap[Op.getValue(1)] = Result.getValue(1); 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SDOperand(Result.Val, Op.ResNo); 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SDOperand PPC32DAGToDAGISel::SelectADD_PARTS(SDOperand Op) { 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDNode *N = Op.Val; 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand LHSL = Select(N->getOperand(0)); 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand LHSH = Select(N->getOperand(1)); 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned Imm; 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool ME = false, ZE = false; 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (isIntImmediate(N->getOperand(3), Imm)) { 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ME = (signed)Imm == -1; 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ZE = Imm == 0; 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<SDOperand> Result; 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand CarryFromLo; 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (isIntImmediate(N->getOperand(2), Imm) && 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((signed)Imm >= -32768 || (signed)Imm < 32768)) { 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Codegen the low 32 bits of the add. Interestingly, there is no 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // shifted form of add immediate carrying. 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CarryFromLo = CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag, 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LHSL, getI32Imm(Imm)); 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CarryFromLo = CurDAG->getTargetNode(PPC::ADDC, MVT::i32, MVT::Flag, 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LHSL, Select(N->getOperand(2))); 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CarryFromLo = CarryFromLo.getValue(1); 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Codegen the high 32 bits, adding zero, minus one, or the full value 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // along with the carry flag produced by addc/addic. 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand ResultHi; 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ZE) 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResultHi = CurDAG->getTargetNode(PPC::ADDZE, MVT::i32, LHSH, CarryFromLo); 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (ME) 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResultHi = CurDAG->getTargetNode(PPC::ADDME, MVT::i32, LHSH, CarryFromLo); 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResultHi = CurDAG->getTargetNode(PPC::ADDE, MVT::i32, LHSH, 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Select(N->getOperand(3)), CarryFromLo); 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Result.push_back(CarryFromLo.getValue(0)); 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Result.push_back(ResultHi); 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CodeGenMap[Op.getValue(0)] = Result[0]; 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CodeGenMap[Op.getValue(1)] = Result[1]; 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Result[Op.ResNo]; 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SDOperand PPC32DAGToDAGISel::SelectSUB_PARTS(SDOperand Op) { 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDNode *N = Op.Val; 76490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SDOperand LHSL = Select(N->getOperand(0)); 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand LHSH = Select(N->getOperand(1)); 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand RHSL = Select(N->getOperand(2)); 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand RHSH = Select(N->getOperand(3)); 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<SDOperand> Result; 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Result.push_back(CurDAG->getTargetNode(PPC::SUBFC, MVT::i32, MVT::Flag, 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RHSL, LHSL)); 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Result.push_back(CurDAG->getTargetNode(PPC::SUBFE, MVT::i32, RHSH, LHSH, 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Result[0].getValue(1))); 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CodeGenMap[Op.getValue(0)] = Result[0]; 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CodeGenMap[Op.getValue(1)] = Result[1]; 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Result[Op.ResNo]; 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SDOperand PPC32DAGToDAGISel::SelectSETCC(SDOperand Op) { 7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDNode *N = Op.Val; 7812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned Imm; 7822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get(); 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (isIntImmediate(N->getOperand(1), Imm)) { 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We can codegen setcc op, imm very efficiently compared to a brcond. 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check for those cases here. 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // setcc op, 0 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Imm == 0) { 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand Op = Select(N->getOperand(0)); 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (CC) { 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: assert(0 && "Unhandled SetCC condition"); abort(); 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::SETEQ: 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Op = CurDAG->getTargetNode(PPC::CNTLZW, MVT::i32, Op); 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Op, getI32Imm(27), 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getI32Imm(5), getI32Imm(31)); 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::SETNE: { 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand AD = CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag, 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Op, getI32Imm(~0U)); 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, AD, Op, AD.getValue(1)); 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::SETLT: 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Op, getI32Imm(1), 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getI32Imm(31), getI32Imm(31)); 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::SETGT: { 8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDOperand T = CurDAG->getTargetNode(PPC::NEG, MVT::i32, Op); 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) T = CurDAG->getTargetNode(PPC::ANDC, MVT::i32, T, Op);; 8092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, T, getI32Imm(1), 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getI32Imm(31), getI32Imm(31)); 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SDOperand(N, 0); 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (Imm == ~0U) { // setcc op, -1 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand Op = Select(N->getOperand(0)); 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (CC) { 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: assert(0 && "Unhandled SetCC condition"); abort(); 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::SETEQ: 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Op = CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag, 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Op, getI32Imm(1)); 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::ADDZE, MVT::i32, 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->getTargetNode(PPC::LI, MVT::i32, 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getI32Imm(0)), 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Op.getValue(1)); 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::SETNE: { 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Op = CurDAG->getTargetNode(PPC::NOR, MVT::i32, Op, Op); 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand AD = CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag, 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Op, getI32Imm(~0U)); 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, AD, Op, AD.getValue(1)); 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::SETLT: { 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand AD = CurDAG->getTargetNode(PPC::ADDI, MVT::i32, Op, 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getI32Imm(1)); 8375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SDOperand AN = CurDAG->getTargetNode(PPC::AND, MVT::i32, AD, Op); 8385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, AN, getI32Imm(1), 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getI32Imm(31), getI32Imm(31)); 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::SETGT: 8435c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu Op = CurDAG->getTargetNode(PPC::RLWINM, MVT::i32, Op, getI32Imm(1), 8445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu getI32Imm(31), getI32Imm(31)); 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::XORI, MVT::i32, Op, getI32Imm(1)); 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SDOperand(N, 0); 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Inv; 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned Idx = getCRIdxForSetCC(CC, Inv); 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand CCReg = SelectCC(N->getOperand(0), N->getOperand(1), CC); 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand IntCR; 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Force the ccreg into CR7. 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand CR7Reg = CurDAG->getRegister(PPC::CR7, MVT::i32); 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<MVT::ValueType> VTs; 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VTs.push_back(MVT::Other); 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VTs.push_back(MVT::Flag); // NONSTANDARD CopyToReg node: defines a flag 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<SDOperand> Ops; 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Ops.push_back(CurDAG->getEntryNode()); 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Ops.push_back(CR7Reg); 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Ops.push_back(CCReg); 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CCReg = CurDAG->getNode(ISD::CopyToReg, VTs, Ops).getValue(1); 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (TLI.getTargetMachine().getSubtarget<PPCSubtarget>().isGigaProcessor()) 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IntCR = CurDAG->getTargetNode(PPC::MFOCRF, MVT::i32, CR7Reg, CCReg); 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IntCR = CurDAG->getTargetNode(PPC::MFCR, MVT::i32, CCReg); 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!Inv) { 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, IntCR, 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getI32Imm(32-(3-Idx)), getI32Imm(31), getI32Imm(31)); 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand Tmp = 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->getTargetNode(PPC::RLWINM, MVT::i32, IntCR, 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getI32Imm(32-(3-Idx)), getI32Imm(31),getI32Imm(31)); 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::XORI, MVT::i32, Tmp, getI32Imm(1)); 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SDOperand(N, 0); 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Select - Convert the specified operand from a target-independent to a 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// target-specific node if it hasn't already been changed. 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SDOperand PPC32DAGToDAGISel::Select(SDOperand Op) { 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDNode *N = Op.Val; 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (N->getOpcode() >= ISD::BUILTIN_OP_END && 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) N->getOpcode() < PPCISD::FIRST_NUMBER) 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Op; // Already selected. 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If this has already been converted, use it. 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<SDOperand, SDOperand>::iterator CGMI = CodeGenMap.find(Op); 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CGMI != CodeGenMap.end()) return CGMI->second; 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (N->getOpcode()) { 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: break; 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::DYNAMIC_STACKALLOC: return SelectDYNAMIC_STACKALLOC(Op); 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::ADD_PARTS: return SelectADD_PARTS(Op); 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::SUB_PARTS: return SelectSUB_PARTS(Op); 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::SETCC: return SelectSETCC(Op); 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::TokenFactor: { 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand New; 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (N->getNumOperands() == 2) { 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand Op0 = Select(N->getOperand(0)); 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand Op1 = Select(N->getOperand(1)); 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) New = CurDAG->getNode(ISD::TokenFactor, MVT::Other, Op0, Op1); 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<SDOperand> Ops; 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Ops.push_back(Select(N->getOperand(i))); 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) New = CurDAG->getNode(ISD::TokenFactor, MVT::Other, Ops); 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!N->hasOneUse()) CodeGenMap[Op] = New; 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return New; 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::CopyFromReg: { 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand Chain = Select(N->getOperand(0)); 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Chain == N->getOperand(0)) return Op; // No change 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand New = CurDAG->getCopyFromReg(Chain, 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cast<RegisterSDNode>(N->getOperand(1))->getReg(), N->getValueType(0)); 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return New.getValue(Op.ResNo); 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::CopyToReg: { 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand Chain = Select(N->getOperand(0)); 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand Reg = N->getOperand(1); 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand Val = Select(N->getOperand(2)); 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand New = CurDAG->getNode(ISD::CopyToReg, MVT::Other, 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Chain, Reg, Val); 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!N->hasOneUse()) CodeGenMap[Op] = New; 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return New; 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::UNDEF: 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (N->getValueType(0) == MVT::i32) 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::IMPLICIT_DEF_GPR, MVT::i32); 9402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else if (N->getValueType(0) == MVT::f32) 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::IMPLICIT_DEF_F4, MVT::f32); 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::IMPLICIT_DEF_F8, MVT::f64); 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SDOperand(N, 0); 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::FrameIndex: { 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int FI = cast<FrameIndexSDNode>(N)->getIndex(); 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::ADDI, MVT::i32, 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->getTargetFrameIndex(FI, MVT::i32), 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getI32Imm(0)); 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SDOperand(N, 0); 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::ConstantPool: { 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Constant *C = cast<ConstantPoolSDNode>(N)->get(); 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand Tmp, CPI = CurDAG->getTargetConstantPool(C, MVT::i32); 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (PICEnabled) 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tmp = CurDAG->getTargetNode(PPC::ADDIS, MVT::i32, getGlobalBaseReg(),CPI); 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tmp = CurDAG->getTargetNode(PPC::LIS, MVT::i32, CPI); 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::LA, MVT::i32, Tmp, CPI); 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SDOperand(N, 0); 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::GlobalAddress: { 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GlobalValue *GV = cast<GlobalAddressSDNode>(N)->getGlobal(); 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand Tmp; 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand GA = CurDAG->getTargetGlobalAddress(GV, MVT::i32); 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (PICEnabled) 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tmp = CurDAG->getTargetNode(PPC::ADDIS, MVT::i32, getGlobalBaseReg(), GA); 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tmp = CurDAG->getTargetNode(PPC::LIS, MVT::i32, GA); 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (GV->hasWeakLinkage() || GV->isExternal()) 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::LWZ, MVT::i32, GA, Tmp); 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::LA, MVT::i32, Tmp, GA); 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SDOperand(N, 0); 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PPCISD::FSEL: { 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand Comparison = Select(N->getOperand(0)); 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Extend the comparison to 64-bits. 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Comparison.getValueType() == MVT::f32) 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Comparison = CurDAG->getTargetNode(PPC::FMRSD, MVT::f64, Comparison); 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned Opc = N->getValueType(0) == MVT::f32 ? PPC::FSELS : PPC::FSELD; 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), Comparison, 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Select(N->getOperand(1)), Select(N->getOperand(2))); 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SDOperand(N, 0); 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PPCISD::FCFID: 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::FCFID, N->getValueType(0), 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Select(N->getOperand(0))); 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SDOperand(N, 0); 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PPCISD::FCTIDZ: 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::FCTIDZ, N->getValueType(0), 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Select(N->getOperand(0))); 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SDOperand(N, 0); 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PPCISD::FCTIWZ: 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::FCTIWZ, N->getValueType(0), 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Select(N->getOperand(0))); 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SDOperand(N, 0); 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::FADD: { 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MVT::ValueType Ty = N->getValueType(0); 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!NoExcessFPPrecision) { // Match FMA ops 10042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (N->getOperand(0).getOpcode() == ISD::FMUL && 10052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) N->getOperand(0).Val->hasOneUse()) { 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++FusedFP; // Statistic 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, Ty == MVT::f64 ? PPC::FMADD : PPC::FMADDS, Ty, 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Select(N->getOperand(0).getOperand(0)), 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Select(N->getOperand(0).getOperand(1)), 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Select(N->getOperand(1))); 10112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return SDOperand(N, 0); 10122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (N->getOperand(1).getOpcode() == ISD::FMUL && 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) N->getOperand(1).hasOneUse()) { 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++FusedFP; // Statistic 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, Ty == MVT::f64 ? PPC::FMADD : PPC::FMADDS, Ty, 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Select(N->getOperand(1).getOperand(0)), 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Select(N->getOperand(1).getOperand(1)), 10182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Select(N->getOperand(0))); 10192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return SDOperand(N, 0); 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, Ty == MVT::f64 ? PPC::FADD : PPC::FADDS, Ty, 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Select(N->getOperand(0)), Select(N->getOperand(1))); 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SDOperand(N, 0); 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::FSUB: { 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MVT::ValueType Ty = N->getValueType(0); 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!NoExcessFPPrecision) { // Match FMA ops 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (N->getOperand(0).getOpcode() == ISD::FMUL && 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) N->getOperand(0).Val->hasOneUse()) { 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++FusedFP; // Statistic 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, Ty == MVT::f64 ? PPC::FMSUB : PPC::FMSUBS, Ty, 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Select(N->getOperand(0).getOperand(0)), 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Select(N->getOperand(0).getOperand(1)), 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Select(N->getOperand(1))); 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SDOperand(N, 0); 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (N->getOperand(1).getOpcode() == ISD::FMUL && 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) N->getOperand(1).Val->hasOneUse()) { 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++FusedFP; // Statistic 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, Ty == MVT::f64 ? PPC::FNMSUB : PPC::FNMSUBS, Ty, 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Select(N->getOperand(1).getOperand(0)), 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Select(N->getOperand(1).getOperand(1)), 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Select(N->getOperand(0))); 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SDOperand(N, 0); 10472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, Ty == MVT::f64 ? PPC::FSUB : PPC::FSUBS, Ty, 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Select(N->getOperand(0)), 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Select(N->getOperand(1))); 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SDOperand(N, 0); 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::SDIV: { 10555c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu unsigned Imm; 10565c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (isIntImmediate(N->getOperand(1), Imm)) { 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((signed)Imm > 0 && isPowerOf2_32(Imm)) { 10582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDOperand Op = 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->getTargetNode(PPC::SRAWI, MVT::i32, MVT::Flag, 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Select(N->getOperand(0)), 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getI32Imm(Log2_32(Imm))); 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::ADDZE, MVT::i32, 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Op.getValue(0), Op.getValue(1)); 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SDOperand(N, 0); 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ((signed)Imm < 0 && isPowerOf2_32(-Imm)) { 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand Op = 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->getTargetNode(PPC::SRAWI, MVT::i32, MVT::Flag, 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Select(N->getOperand(0)), 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getI32Imm(Log2_32(-Imm))); 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand PT = 10712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CurDAG->getTargetNode(PPC::ADDZE, MVT::i32, Op.getValue(0), 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Op.getValue(1)); 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::NEG, MVT::i32, PT); 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SDOperand(N, 0); 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (Imm) { 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand Result = Select(BuildSDIVSequence(N)); 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CodeGenMap[Op] = Result; 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Result; 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Other cases are autogenerated. 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ISD::UDIV: { 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If this is a divide by constant, we can emit code using some magic 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // constants to implement it as a multiply instead. 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned Imm; 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (isIntImmediate(N->getOperand(1), Imm) && Imm) { 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand Result = Select(BuildUDIVSequence(N)); 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CodeGenMap[Op] = Result; 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Result; 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu // Other cases are autogenerated. 10965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu break; 10975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu } 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::AND: { 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned Imm; 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If this is an and of a value rotated between 0 and 31 bits and then and'd 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // with a mask, emit rlwinm 11022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (isIntImmediate(N->getOperand(1), Imm) && (isShiftedMask_32(Imm) || 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) isShiftedMask_32(~Imm))) { 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand Val; 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned SH, MB, ME; 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (isRotateAndMask(N->getOperand(0).Val, Imm, false, SH, MB, ME)) { 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Val = Select(N->getOperand(0).getOperand(0)); 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Val = Select(N->getOperand(0)); 11102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) isRunOfOnes(Imm, MB, ME); 11112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SH = 0; 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Val, getI32Imm(SH), 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getI32Imm(MB), getI32Imm(ME)); 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SDOperand(N, 0); 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Other cases are autogenerated. 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::OR: 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SDNode *I = SelectBitfieldInsert(N)) 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CodeGenMap[Op] = SDOperand(I, 0); 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SDNode *I = SelectIntImmediateExpr(N->getOperand(0), 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) N->getOperand(1), 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PPC::ORIS, PPC::ORI)) 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CodeGenMap[Op] = SDOperand(I, 0); 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Other cases are autogenerated. 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 11322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ISD::SHL: { 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned Imm, SH, MB, ME; 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (isOpcWithIntImmediate(N->getOperand(0).Val, ISD::AND, Imm) && 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) isRotateAndMask(N, Imm, true, SH, MB, ME)) 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Select(N->getOperand(0).getOperand(0)), 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getI32Imm(SH), getI32Imm(MB), getI32Imm(ME)); 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (isIntImmediate(N->getOperand(1), Imm)) 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Select(N->getOperand(0)), 11412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) getI32Imm(Imm), getI32Imm(0), getI32Imm(31-Imm)); 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::SLW, MVT::i32, Select(N->getOperand(0)), 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Select(N->getOperand(1))); 11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SDOperand(N, 0); 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::SRL: { 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned Imm, SH, MB, ME; 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (isOpcWithIntImmediate(N->getOperand(0).Val, ISD::AND, Imm) && 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) isRotateAndMask(N, Imm, true, SH, MB, ME)) 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Select(N->getOperand(0).getOperand(0)), 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getI32Imm(SH & 0x1F), getI32Imm(MB), getI32Imm(ME)); 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (isIntImmediate(N->getOperand(1), Imm)) 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, Select(N->getOperand(0)), 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getI32Imm((32-Imm) & 0x1F), getI32Imm(Imm), 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getI32Imm(31)); 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::SRW, MVT::i32, Select(N->getOperand(0)), 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Select(N->getOperand(1))); 11612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return SDOperand(N, 0); 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::SRA: { 11642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned Imm, SH, MB, ME; 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (isOpcWithIntImmediate(N->getOperand(0).Val, ISD::AND, Imm) && 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) isRotateAndMask(N, Imm, true, SH, MB, ME)) 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::RLWINM, MVT::i32, 11682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Select(N->getOperand(0).getOperand(0)), 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getI32Imm(SH), getI32Imm(MB), getI32Imm(ME)); 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (isIntImmediate(N->getOperand(1), Imm)) 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::SRAWI, MVT::i32, Select(N->getOperand(0)), 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getI32Imm(Imm)); 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 11742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::SRAW, MVT::i32, Select(N->getOperand(0)), 11752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Select(N->getOperand(1))); 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SDOperand(N, 0); 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::FMUL: { 11792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned Opc = N->getValueType(0) == MVT::f32 ? PPC::FMULS : PPC::FMUL; 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), Select(N->getOperand(0)), 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Select(N->getOperand(1))); 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SDOperand(N, 0); 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::FDIV: { 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned Opc = N->getValueType(0) == MVT::f32 ? PPC::FDIVS : PPC::FDIV; 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), Select(N->getOperand(0)), 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Select(N->getOperand(1))); 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SDOperand(N, 0); 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::FABS: 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (N->getValueType(0) == MVT::f32) 11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::FABSS, MVT::f32, Select(N->getOperand(0))); 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::FABSD, MVT::f64, Select(N->getOperand(0))); 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SDOperand(N, 0); 11962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ISD::FP_EXTEND: 11972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) assert(MVT::f64 == N->getValueType(0) && 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MVT::f32 == N->getOperand(0).getValueType() && "Illegal FP_EXTEND"); 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We need to emit an FMR to make sure that the result has the right value 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // type. 12012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::FMRSD, MVT::f64, Select(N->getOperand(0))); 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SDOperand(N, 0); 12032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ISD::FP_ROUND: 12042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) assert(MVT::f32 == N->getValueType(0) && 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MVT::f64 == N->getOperand(0).getValueType() && "Illegal FP_ROUND"); 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::FRSP, MVT::f32, Select(N->getOperand(0))); 12072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return SDOperand(N, 0); 12082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ISD::FNEG: { 12092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDOperand Val = Select(N->getOperand(0)); 12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MVT::ValueType Ty = N->getValueType(0); 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Val.Val->hasOneUse()) { 12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned Opc; 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (Val.isTargetOpcode() ? Val.getTargetOpcode() : 0) { 12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: Opc = 0; break; 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PPC::FABSS: Opc = PPC::FNABSS; break; 12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PPC::FABSD: Opc = PPC::FNABSD; break; 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PPC::FMADD: Opc = PPC::FNMADD; break; 12185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu case PPC::FMADDS: Opc = PPC::FNMADDS; break; 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PPC::FMSUB: Opc = PPC::FNMSUB; break; 12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PPC::FMSUBS: Opc = PPC::FNMSUBS; break; 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we inverted the opcode, then emit the new instruction with the 12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // inverted opcode and the original instruction's operands. Otherwise, 12242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // fall through and generate a fneg instruction. 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Opc) { 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Opc == PPC::FNABSS || Opc == PPC::FNABSD) 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, Opc, Ty, Val.getOperand(0)); 12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, Opc, Ty, Val.getOperand(0), 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Val.getOperand(1), Val.getOperand(2)); 12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SDOperand(N, 0); 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Ty == MVT::f32) 12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::FNEGS, MVT::f32, Val); 12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::FNEGD, MVT::f64, Val); 12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SDOperand(N, 0); 12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::FSQRT: { 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MVT::ValueType Ty = N->getValueType(0); 12422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CurDAG->SelectNodeTo(N, Ty == MVT::f64 ? PPC::FSQRT : PPC::FSQRTS, Ty, 12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Select(N->getOperand(0))); 12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SDOperand(N, 0); 12452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::LOAD: 12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::EXTLOAD: 12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::ZEXTLOAD: 12502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ISD::SEXTLOAD: { 12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand Op1, Op2; 12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool isIdx = SelectAddr(N->getOperand(1), Op1, Op2); 12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MVT::ValueType TypeBeingLoaded = (N->getOpcode() == ISD::LOAD) ? 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) N->getValueType(0) : cast<VTSDNode>(N->getOperand(3))->getVT(); 12562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned Opc; 12572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch (TypeBeingLoaded) { 12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: N->dump(); assert(0 && "Cannot load this type!"); 12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MVT::i1: 12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MVT::i8: Opc = isIdx ? PPC::LBZX : PPC::LBZ; break; 12612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case MVT::i16: 12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (N->getOpcode() == ISD::SEXTLOAD) { // SEXT load? 12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Opc = isIdx ? PPC::LHAX : PPC::LHA; 12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Opc = isIdx ? PPC::LHZX : PPC::LHZ; 12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MVT::i32: Opc = isIdx ? PPC::LWZX : PPC::LWZ; break; 12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MVT::f32: Opc = isIdx ? PPC::LFSX : PPC::LFS; break; 12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MVT::f64: Opc = isIdx ? PPC::LFDX : PPC::LFD; break; 12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If this is an f32 -> f64 load, emit the f32 load, then use an 'extending 12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // copy'. 12752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (TypeBeingLoaded != MVT::f32 || N->getOpcode() == ISD::LOAD) { 12762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), MVT::Other, 12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Op1, Op2, Select(N->getOperand(0))); 12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SDOperand(N, Op.ResNo); 12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<SDOperand> Ops; 12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Ops.push_back(Op1); 12822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Ops.push_back(Op2); 12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Ops.push_back(Select(N->getOperand(0))); 12842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDOperand Res = CurDAG->getTargetNode(Opc, MVT::f32, MVT::Other, Ops); 12852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDOperand Ext = CurDAG->getTargetNode(PPC::FMRSD, MVT::f64, Res); 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CodeGenMap[Op.getValue(0)] = Ext; 12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CodeGenMap[Op.getValue(1)] = Res.getValue(1); 12882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (Op.ResNo) 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return Res.getValue(1); 12902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 12912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return Ext; 12922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::TRUNCSTORE: 12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::STORE: { 12975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SDOperand AddrOp1, AddrOp2; 12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool isIdx = SelectAddr(N->getOperand(2), AddrOp1, AddrOp2); 12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned Opc; 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (N->getOpcode() == ISD::STORE) { 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (N->getOperand(1).getValueType()) { 13032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: assert(0 && "unknown Type in store"); 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MVT::i32: Opc = isIdx ? PPC::STWX : PPC::STW; break; 13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MVT::f64: Opc = isIdx ? PPC::STFDX : PPC::STFD; break; 13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MVT::f32: Opc = isIdx ? PPC::STFSX : PPC::STFS; break; 13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { //ISD::TRUNCSTORE 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch(cast<VTSDNode>(N->getOperand(4))->getVT()) { 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: assert(0 && "unknown Type in store"); 13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MVT::i8: Opc = isIdx ? PPC::STBX : PPC::STB; break; 13122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case MVT::i16: Opc = isIdx ? PPC::STHX : PPC::STH; break; 13132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, Opc, MVT::Other, Select(N->getOperand(1)), 13172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AddrOp1, AddrOp2, Select(N->getOperand(0))); 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SDOperand(N, 0); 13192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 13202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::SELECT_CC: { 13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(4))->get(); 1323a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1324a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // handle the setcc cases here. select_cc lhs, 0, 1, 0, cc 1325a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (ConstantSDNode *N1C = dyn_cast<ConstantSDNode>(N->getOperand(1))) 13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ConstantSDNode *N2C = dyn_cast<ConstantSDNode>(N->getOperand(2))) 13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ConstantSDNode *N3C = dyn_cast<ConstantSDNode>(N->getOperand(3))) 13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (N1C->isNullValue() && N3C->isNullValue() && 13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) N2C->getValue() == 1ULL && CC == ISD::SETNE) { 13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand LHS = Select(N->getOperand(0)); 13315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu SDOperand Tmp = 13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->getTargetNode(PPC::ADDIC, MVT::i32, MVT::Flag, 13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LHS, getI32Imm(~0U)); 13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::SUBFE, MVT::i32, Tmp, LHS, 13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Tmp.getValue(1)); 13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SDOperand(N, 0); 13372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand CCReg = SelectCC(N->getOperand(0), N->getOperand(1), CC); 13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned BROpc = getBCCForSetCC(CC); 13412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool isFP = MVT::isFloatingPoint(N->getValueType(0)); 13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned SelectCCOp; 13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (MVT::isInteger(N->getValueType(0))) 13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SelectCCOp = PPC::SELECT_CC_Int; 13462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else if (N->getValueType(0) == MVT::f32) 13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SelectCCOp = PPC::SELECT_CC_F4; 13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SelectCCOp = PPC::SELECT_CC_F8; 13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, SelectCCOp, N->getValueType(0), CCReg, 13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Select(N->getOperand(2)), Select(N->getOperand(3)), 13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getI32Imm(BROpc)); 13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SDOperand(N, 0); 13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::CALLSEQ_START: 13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::CALLSEQ_END: { 13582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned Amt = cast<ConstantSDNode>(N->getOperand(1))->getValue(); 13592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned Opc = N->getOpcode() == ISD::CALLSEQ_START ? 13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PPC::ADJCALLSTACKDOWN : PPC::ADJCALLSTACKUP; 13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, Opc, MVT::Other, 13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getI32Imm(Amt), Select(N->getOperand(0))); 13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SDOperand(N, 0); 13642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::CALL: 13662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ISD::TAILCALL: { 13672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDOperand Chain = Select(N->getOperand(0)); 13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned CallOpcode; 1370a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) std::vector<SDOperand> CallOperands; 1371a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1372a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) if (GlobalAddressSDNode *GASD = 13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dyn_cast<GlobalAddressSDNode>(N->getOperand(1))) { 13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CallOpcode = PPC::CALLpcrel; 13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CallOperands.push_back(CurDAG->getTargetGlobalAddress(GASD->getGlobal(), 13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MVT::i32)); 13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (ExternalSymbolSDNode *ESSDN = 13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dyn_cast<ExternalSymbolSDNode>(N->getOperand(1))) { 13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CallOpcode = PPC::CALLpcrel; 13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CallOperands.push_back(N->getOperand(1)); 13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Copy the callee address into the CTR register. 13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand Callee = Select(N->getOperand(1)); 13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Chain = CurDAG->getTargetNode(PPC::MTCTR, MVT::Other, Callee, Chain); 13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Copy the callee address into R12 on darwin. 13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand R12 = CurDAG->getRegister(PPC::R12, MVT::i32); 13882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Chain = CurDAG->getNode(ISD::CopyToReg, MVT::Other, Chain, R12, Callee); 13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CallOperands.push_back(getI32Imm(20)); // Information to encode indcall 13912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CallOperands.push_back(getI32Imm(0)); // Information to encode indcall 13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CallOperands.push_back(R12); 13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CallOpcode = PPC::CALLindirect; 13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned GPR_idx = 0, FPR_idx = 0; 13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const unsigned GPR[] = { 13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PPC::R3, PPC::R4, PPC::R5, PPC::R6, 13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PPC::R7, PPC::R8, PPC::R9, PPC::R10, 14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const unsigned FPR[] = { 14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7, 14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13 14042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) }; 14052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDOperand InFlag; // Null incoming flag value. 14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned i = 2, e = N->getNumOperands(); i != e; ++i) { 14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned DestReg = 0; 14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MVT::ValueType RegTy = N->getOperand(i).getValueType(); 14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (RegTy == MVT::i32) { 14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(GPR_idx < 8 && "Too many int args"); 14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DestReg = GPR[GPR_idx++]; 14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(MVT::isFloatingPoint(N->getOperand(i).getValueType()) && 14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Unpromoted integer arg?"); 14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(FPR_idx < 13 && "Too many fp args"); 14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DestReg = FPR[FPR_idx++]; 14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (N->getOperand(i).getOpcode() != ISD::UNDEF) { 14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand Val = Select(N->getOperand(i)); 14232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Chain = CurDAG->getCopyToReg(Chain, DestReg, Val, InFlag); 14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InFlag = Chain.getValue(1); 14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CallOperands.push_back(CurDAG->getRegister(DestReg, RegTy)); 14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Finally, once everything is in registers to pass to the call, emit the 14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // call itself. 14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (InFlag.Val) 14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CallOperands.push_back(InFlag); // Strong dep on register copies. 14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CallOperands.push_back(Chain); // Weak dep on whatever occurs before 14352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Chain = CurDAG->getTargetNode(CallOpcode, MVT::Other, MVT::Flag, 14362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CallOperands); 14372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<SDOperand> CallResults; 14392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If the call has results, copy the values out of the ret val registers. 14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (N->getValueType(0)) { 14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: assert(0 && "Unexpected ret value!"); 14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MVT::Other: break; 14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MVT::i32: 14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (N->getValueType(1) == MVT::i32) { 14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Chain = CurDAG->getCopyFromReg(Chain, PPC::R4, MVT::i32, 14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Chain.getValue(1)).getValue(1); 14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CallResults.push_back(Chain.getValue(0)); 14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Chain = CurDAG->getCopyFromReg(Chain, PPC::R3, MVT::i32, 14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Chain.getValue(2)).getValue(1); 14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CallResults.push_back(Chain.getValue(0)); 14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Chain = CurDAG->getCopyFromReg(Chain, PPC::R3, MVT::i32, 14542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Chain.getValue(1)).getValue(1); 14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CallResults.push_back(Chain.getValue(0)); 14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MVT::f32: 14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case MVT::f64: 14602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Chain = CurDAG->getCopyFromReg(Chain, PPC::F1, N->getValueType(0), 14612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Chain.getValue(1)).getValue(1); 14622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CallResults.push_back(Chain.getValue(0)); 14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CallResults.push_back(Chain); 14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (unsigned i = 0, e = CallResults.size(); i != e; ++i) 14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CodeGenMap[Op.getValue(i)] = CallResults[i]; 14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CallResults[Op.ResNo]; 14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::RET: { 14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand Chain = Select(N->getOperand(0)); // Token chain. 14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (N->getNumOperands() == 2) { 14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand Val = Select(N->getOperand(1)); 14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (N->getOperand(1).getValueType() == MVT::i32) { 14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Chain = CurDAG->getCopyToReg(Chain, PPC::R3, Val); 14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(MVT::isFloatingPoint(N->getOperand(1).getValueType())); 14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Chain = CurDAG->getCopyToReg(Chain, PPC::F1, Val); 14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (N->getNumOperands() > 1) { 14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) assert(N->getOperand(1).getValueType() == MVT::i32 && 14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) N->getOperand(2).getValueType() == MVT::i32 && 14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) N->getNumOperands() == 3 && "Unknown two-register ret value!"); 14862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Chain = CurDAG->getCopyToReg(Chain, PPC::R4, Select(N->getOperand(1))); 14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Chain = CurDAG->getCopyToReg(Chain, PPC::R3, Select(N->getOperand(2))); 14882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Finally, select this to a blr (return) instruction. 14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::BLR, MVT::Other, Chain); 14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SDOperand(N, 0); 14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::BR: 14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::B, MVT::Other, N->getOperand(1), 14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Select(N->getOperand(0))); 14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SDOperand(N, 0); 14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::BR_CC: 14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::BRTWOWAY_CC: { 15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand Chain = Select(N->getOperand(0)); 15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MachineBasicBlock *Dest = 15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cast<BasicBlockSDNode>(N->getOperand(4))->getBasicBlock(); 15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(1))->get(); 15042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDOperand CondCode = SelectCC(N->getOperand(2), N->getOperand(3), CC); 15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If this is a two way branch, then grab the fallthrough basic block 15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // argument and build a PowerPC branch pseudo-op, suitable for long branch 15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // conversion if necessary by the branch selection pass. Otherwise, emit a 15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // standard conditional branch. 15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (N->getOpcode() == ISD::BRTWOWAY_CC) { 15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand CondTrueBlock = N->getOperand(4); 15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand CondFalseBlock = N->getOperand(5); 15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the false case is the current basic block, then this is a self loop. 15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We do not want to emit "Loop: ... brcond Out; br Loop", as it adds an 15162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // extra dispatch group to the loop. Instead, invert the condition and 15172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // emit "Loop: ... br!cond Loop; br Out 15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cast<BasicBlockSDNode>(CondFalseBlock)->getBasicBlock() == BB) { 15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::swap(CondTrueBlock, CondFalseBlock); 15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CC = getSetCCInverse(CC, 15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MVT::isInteger(N->getOperand(2).getValueType())); 15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned Opc = getBCCForSetCC(CC); 15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SDOperand CB = CurDAG->getTargetNode(PPC::COND_BRANCH, MVT::Other, 15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CondCode, getI32Imm(Opc), 15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CondTrueBlock, CondFalseBlock, 15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Chain); 15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::B, MVT::Other, CondFalseBlock, CB); 15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Iterate to the next basic block 15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ilist<MachineBasicBlock>::iterator It = BB; 15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++It; 15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the fallthrough path is off the end of the function, which would be 15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // undefined behavior, set it to be the same as the current block because 15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we have nothing better to set it to, and leaving it alone will cause 15382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the PowerPC Branch Selection pass to crash. 15392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (It == BB->getParent()->end()) It = Dest; 15402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CurDAG->SelectNodeTo(N, PPC::COND_BRANCH, MVT::Other, CondCode, 15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) getI32Imm(getBCCForSetCC(CC)), N->getOperand(4), 15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CurDAG->getBasicBlock(It), Chain); 15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SDOperand(N, 0); 15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return SelectCode(Op); 15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// createPPC32ISelDag - This pass converts a legalized DAG into a 15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// PowerPC-specific DAG, ready for instruction scheduling. 15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// 15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)FunctionPass *llvm::createPPC32ISelDag(TargetMachine &TM) { 15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new PPC32DAGToDAGISel(TM); 15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)