PPCISelLowering.cpp revision 5b3224fe7ecafd486b75ebfa113a95783112ec3d
1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project//===-- PPC32ISelLowering.cpp - PPC32 DAG Lowering Implementation ---------===//
2656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project//
3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project//                     The LLVM Compiler Infrastructure
4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project//
5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project// This file was developed by Chris Lattner and is distributed under
6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project// the University of Illinois Open Source License. See LICENSE.TXT for details.
7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project//
8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project//===----------------------------------------------------------------------===//
9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project//
10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project// This file implements the PPC32ISelLowering class.
11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project//
12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project//===----------------------------------------------------------------------===//
13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "PPC32ISelLowering.h"
15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "PPC32TargetMachine.h"
16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "llvm/CodeGen/MachineFrameInfo.h"
17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "llvm/CodeGen/MachineFunction.h"
18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "llvm/CodeGen/MachineInstrBuilder.h"
19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "llvm/CodeGen/SelectionDAG.h"
20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "llvm/Constants.h"
21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "llvm/Function.h"
22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectusing namespace llvm;
23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectPPC32TargetLowering::PPC32TargetLowering(TargetMachine &TM)
25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  : TargetLowering(TM) {
26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // Fold away setcc operations if possible.
28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  setSetCCIsExpensive();
29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // Set up the register classes.
31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  addRegisterClass(MVT::i32, PPC32::GPRCRegisterClass);
32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  addRegisterClass(MVT::f32, PPC32::FPRCRegisterClass);
33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  addRegisterClass(MVT::f64, PPC32::FPRCRegisterClass);
34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // PowerPC has no intrinsics for these particular operations
36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  setOperationAction(ISD::MEMMOVE, MVT::Other, Expand);
37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  setOperationAction(ISD::MEMSET, MVT::Other, Expand);
38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  setOperationAction(ISD::MEMCPY, MVT::Other, Expand);
39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // PowerPC has an i16 but no i8 (or i1) SEXTLOAD
41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  setOperationAction(ISD::SEXTLOAD, MVT::i1, Expand);
42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  setOperationAction(ISD::SEXTLOAD, MVT::i8, Expand);
43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // PowerPC has no SREM/UREM instructions
45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  setOperationAction(ISD::SREM, MVT::i32, Expand);
46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  setOperationAction(ISD::UREM, MVT::i32, Expand);
47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // We don't support sin/cos/sqrt/fmod
49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  setOperationAction(ISD::FSIN , MVT::f64, Expand);
50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  setOperationAction(ISD::FCOS , MVT::f64, Expand);
51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  setOperationAction(ISD::SREM , MVT::f64, Expand);
52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  setOperationAction(ISD::FSIN , MVT::f32, Expand);
53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  setOperationAction(ISD::FCOS , MVT::f32, Expand);
54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  setOperationAction(ISD::SREM , MVT::f32, Expand);
55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // If we're enabling GP optimizations, use hardware square root
57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  if (!TM.getSubtarget<PPCSubtarget>().isGigaProcessor()) {
58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    setOperationAction(ISD::FSQRT, MVT::f64, Expand);
59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    setOperationAction(ISD::FSQRT, MVT::f32, Expand);
60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  }
61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // PowerPC does not have CTPOP or CTTZ
63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  setOperationAction(ISD::CTPOP, MVT::i32  , Expand);
64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  setOperationAction(ISD::CTTZ , MVT::i32  , Expand);
65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // PowerPC does not have Select
67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  setOperationAction(ISD::SELECT, MVT::i32, Expand);
68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  setOperationAction(ISD::SELECT, MVT::f32, Expand);
69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  setOperationAction(ISD::SELECT, MVT::f64, Expand);
70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // PowerPC wants to turn select_cc of FP into fsel when possible.
72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  setOperationAction(ISD::SELECT_CC, MVT::f32, Custom);
73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  setOperationAction(ISD::SELECT_CC, MVT::f64, Custom);
74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
75656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // PowerPC wants to expand i64 shifts itself.
76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  setOperationAction(ISD::SHL, MVT::i64, Custom);
77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  setOperationAction(ISD::SRL, MVT::i64, Custom);
78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  setOperationAction(ISD::SRA, MVT::i64, Custom);
79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // PowerPC does not have BRCOND* which requires SetCC
81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  setOperationAction(ISD::BRCOND,       MVT::Other, Expand);
82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  setOperationAction(ISD::BRCONDTWOWAY, MVT::Other, Expand);
83656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // PowerPC does not have FP_TO_UINT
85656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand);
86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
87656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // PowerPC turns FP_TO_SINT into FCTIWZ and some load/stores.
88656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom);
89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // PowerPC does not have [U|S]INT_TO_FP
91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  setOperationAction(ISD::SINT_TO_FP, MVT::i32, Expand);
92656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand);
93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  setSetCCResultContents(ZeroOrOneSetCCResult);
95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  computeRegisterProperties();
97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/// isFloatingPointZero - Return true if this is 0.0 or -0.0.
100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic bool isFloatingPointZero(SDOperand Op) {
101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(Op))
102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    return CFP->isExactlyValue(-0.0) || CFP->isExactlyValue(0.0);
103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  else if (Op.getOpcode() == ISD::EXTLOAD || Op.getOpcode() == ISD::LOAD) {
104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    // Maybe this has already been legalized into the constant pool?
105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if (ConstantPoolSDNode *CP = dyn_cast<ConstantPoolSDNode>(Op.getOperand(1)))
106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      if (ConstantFP *CFP = dyn_cast<ConstantFP>(CP->get()))
107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        return CFP->isExactlyValue(-0.0) || CFP->isExactlyValue(0.0);
108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  }
109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  return false;
110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/// LowerOperation - Provide custom lowering hooks for some operations.
113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project///
114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectSDOperand PPC32TargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) {
115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  switch (Op.getOpcode()) {
116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  default: assert(0 && "Wasn't expecting to be able to lower this!");
117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  case ISD::FP_TO_SINT: {
118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    assert(Op.getValueType() == MVT::i32 &&
119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project           MVT::isFloatingPoint(Op.getOperand(0).getValueType()));
120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    Op = DAG.getNode(PPCISD::FCTIWZ, MVT::f64, Op.getOperand(0));
121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    int FrameIdx =
123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      DAG.getMachineFunction().getFrameInfo()->CreateStackObject(8, 8);
124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand FI = DAG.getFrameIndex(FrameIdx, MVT::i32);
125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand ST = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(),
126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                               Op, FI, DAG.getSrcValue(0));
127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    FI = DAG.getNode(ISD::ADD, MVT::i32, FI, DAG.getConstant(4, MVT::i32));
128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    return DAG.getLoad(MVT::i32, ST, FI, DAG.getSrcValue(0));
129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  }
130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  case ISD::SELECT_CC: {
131656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    // Turn FP only select_cc's into fsel instructions.
132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if (!MVT::isFloatingPoint(Op.getOperand(0).getValueType()) ||
133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        !MVT::isFloatingPoint(Op.getOperand(2).getValueType()))
134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      break;
135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get();
137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    // Cannot handle SETEQ/SETNE.
139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if (CC == ISD::SETEQ || CC == ISD::SETNE) break;
140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    MVT::ValueType ResVT = Op.getValueType();
142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    MVT::ValueType CmpVT = Op.getOperand(0).getValueType();
143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand LHS = Op.getOperand(0), RHS = Op.getOperand(1);
144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand TV  = Op.getOperand(2), FV  = Op.getOperand(3);
145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    // If the RHS of the comparison is a 0.0, we don't need to do the
147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    // subtraction at all.
148656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if (isFloatingPointZero(RHS))
149656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      switch (CC) {
150656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      default: assert(0 && "Invalid FSEL condition"); abort();
151656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      case ISD::SETULT:
152656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      case ISD::SETLT:
153656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        std::swap(TV, FV);  // fsel is natively setge, swap operands for setlt
154656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      case ISD::SETUGE:
155656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      case ISD::SETGE:
156656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        return DAG.getNode(PPCISD::FSEL, ResVT, LHS, TV, FV);
157656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      case ISD::SETUGT:
158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      case ISD::SETGT:
159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        std::swap(TV, FV);  // fsel is natively setge, swap operands for setlt
160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      case ISD::SETULE:
161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      case ISD::SETLE:
162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        return DAG.getNode(PPCISD::FSEL, ResVT,
163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                           DAG.getNode(ISD::FNEG, ResVT, LHS), TV, FV);
164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      }
165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    switch (CC) {
167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    default: assert(0 && "Invalid FSEL condition"); abort();
168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    case ISD::SETULT:
169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    case ISD::SETLT:
170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      return DAG.getNode(PPCISD::FSEL, ResVT,
171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                         DAG.getNode(ISD::SUB, CmpVT, LHS, RHS), FV, TV);
172656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    case ISD::SETUGE:
173656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    case ISD::SETGE:
174656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      return DAG.getNode(PPCISD::FSEL, ResVT,
175656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                         DAG.getNode(ISD::SUB, CmpVT, LHS, RHS), TV, FV);
176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    case ISD::SETUGT:
177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    case ISD::SETGT:
178656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      return DAG.getNode(PPCISD::FSEL, ResVT,
179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                         DAG.getNode(ISD::SUB, CmpVT, RHS, LHS), FV, TV);
180656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    case ISD::SETULE:
181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    case ISD::SETLE:
182656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      return DAG.getNode(PPCISD::FSEL, ResVT,
183656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                         DAG.getNode(ISD::SUB, CmpVT, RHS, LHS), TV, FV);
184656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    }
185656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    break;
186656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  }
187656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  case ISD::SHL: {
188656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    assert(Op.getValueType() == MVT::i64 &&
189656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project           Op.getOperand(1).getValueType() == MVT::i32 && "Unexpected SHL!");
190656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    // The generic code does a fine job expanding shift by a constant.
191656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if (isa<ConstantSDNode>(Op.getOperand(1))) break;
192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    // Otherwise, expand into a bunch of logical ops.  Note that these ops
194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    // depend on the PPC behavior for oversized shift amounts.
195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0),
196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                               DAG.getConstant(0, MVT::i32));
197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0),
198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                               DAG.getConstant(1, MVT::i32));
199656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand Amt = Op.getOperand(1);
200656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32,
202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                 DAG.getConstant(32, MVT::i32), Amt);
203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand Tmp2 = DAG.getNode(ISD::SHL, MVT::i32, Hi, Amt);
204656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand Tmp3 = DAG.getNode(ISD::SRL, MVT::i32, Lo, Tmp1);
205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand Tmp4 = DAG.getNode(ISD::OR , MVT::i32, Tmp2, Tmp3);
206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand Tmp5 = DAG.getNode(ISD::ADD, MVT::i32, Amt,
207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                 DAG.getConstant(-32U, MVT::i32));
208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand Tmp6 = DAG.getNode(ISD::SHL, MVT::i32, Lo, Tmp5);
209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand OutHi = DAG.getNode(ISD::OR, MVT::i32, Tmp4, Tmp6);
210656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand OutLo = DAG.getNode(ISD::SHL, MVT::i32, Lo, Amt);
211656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi);
212656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  }
213656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  case ISD::SRL: {
214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    assert(Op.getValueType() == MVT::i64 &&
215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project           Op.getOperand(1).getValueType() == MVT::i32 && "Unexpected SHL!");
216656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    // The generic code does a fine job expanding shift by a constant.
217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if (isa<ConstantSDNode>(Op.getOperand(1))) break;
218656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    // Otherwise, expand into a bunch of logical ops.  Note that these ops
220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    // depend on the PPC behavior for oversized shift amounts.
221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0),
222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                               DAG.getConstant(0, MVT::i32));
223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0),
224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                               DAG.getConstant(1, MVT::i32));
225656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand Amt = Op.getOperand(1);
226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32,
228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                 DAG.getConstant(32, MVT::i32), Amt);
229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand Tmp2 = DAG.getNode(ISD::SRL, MVT::i32, Lo, Amt);
230656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand Tmp3 = DAG.getNode(ISD::SHL, MVT::i32, Hi, Tmp1);
231656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand Tmp4 = DAG.getNode(ISD::OR , MVT::i32, Tmp2, Tmp3);
232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand Tmp5 = DAG.getNode(ISD::ADD, MVT::i32, Amt,
233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                 DAG.getConstant(-32U, MVT::i32));
234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand Tmp6 = DAG.getNode(ISD::SRL, MVT::i32, Hi, Tmp5);
235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand OutLo = DAG.getNode(ISD::OR, MVT::i32, Tmp4, Tmp6);
236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand OutHi = DAG.getNode(ISD::SRL, MVT::i32, Hi, Amt);
237656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi);
238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  }
239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  case ISD::SRA: {
240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    assert(Op.getValueType() == MVT::i64 &&
241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project           Op.getOperand(1).getValueType() == MVT::i32 && "Unexpected SRA!");
242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    // The generic code does a fine job expanding shift by a constant.
243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if (isa<ConstantSDNode>(Op.getOperand(1))) break;
244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
245656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    // Otherwise, expand into a bunch of logical ops, followed by a select_cc.
246656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0),
247656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                               DAG.getConstant(0, MVT::i32));
248656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op.getOperand(0),
249656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                               DAG.getConstant(1, MVT::i32));
250656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand Amt = Op.getOperand(1);
251656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
252656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand Tmp1 = DAG.getNode(ISD::SUB, MVT::i32,
253656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                 DAG.getConstant(32, MVT::i32), Amt);
254656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand Tmp2 = DAG.getNode(ISD::SRL, MVT::i32, Lo, Amt);
255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand Tmp3 = DAG.getNode(ISD::SHL, MVT::i32, Hi, Tmp1);
256656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand Tmp4 = DAG.getNode(ISD::OR , MVT::i32, Tmp2, Tmp3);
257656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand Tmp5 = DAG.getNode(ISD::ADD, MVT::i32, Amt,
258656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                 DAG.getConstant(-32U, MVT::i32));
259656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand Tmp6 = DAG.getNode(ISD::SRA, MVT::i32, Hi, Tmp5);
260656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand OutHi = DAG.getNode(ISD::SRA, MVT::i32, Hi, Amt);
261656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand OutLo = DAG.getSelectCC(Tmp5, DAG.getConstant(0, MVT::i32),
262656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                      Tmp4, Tmp6, ISD::SETLE);
263656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    return DAG.getNode(ISD::BUILD_PAIR, MVT::i64, OutLo, OutHi);
264656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  }
265656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  }
266656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  return SDOperand();
267656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
268656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
269656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstd::vector<SDOperand>
270656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectPPC32TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) {
271656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  //
272656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // add beautiful description of PPC stack frame format, or at least some docs
273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  //
274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  MachineFunction &MF = DAG.getMachineFunction();
275656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  MachineFrameInfo *MFI = MF.getFrameInfo();
276656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  MachineBasicBlock& BB = MF.front();
277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  std::vector<SDOperand> ArgValues;
278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // Due to the rather complicated nature of the PowerPC ABI, rather than a
280656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // fixed size array of physical args, for the sake of simplicity let the STL
281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // handle tracking them for us.
282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  std::vector<unsigned> argVR, argPR, argOp;
283656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  unsigned ArgOffset = 24;
284656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  unsigned GPR_remaining = 8;
285656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  unsigned FPR_remaining = 13;
286656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  unsigned GPR_idx = 0, FPR_idx = 0;
287656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  static const unsigned GPR[] = {
288656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    PPC::R3, PPC::R4, PPC::R5, PPC::R6,
289656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    PPC::R7, PPC::R8, PPC::R9, PPC::R10,
290656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  };
291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  static const unsigned FPR[] = {
292656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    PPC::F1, PPC::F2, PPC::F3, PPC::F4, PPC::F5, PPC::F6, PPC::F7,
293656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    PPC::F8, PPC::F9, PPC::F10, PPC::F11, PPC::F12, PPC::F13
294656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  };
295656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
296656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // Add DAG nodes to load the arguments...  On entry to a function on PPC,
297656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // the arguments start at offset 24, although they are likely to be passed
298656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // in registers.
299656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) {
300656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand newroot, argt;
301656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    unsigned ObjSize;
302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    bool needsLoad = false;
303656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    bool ArgLive = !I->use_empty();
304656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    MVT::ValueType ObjectVT = getValueType(I->getType());
305656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
306656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    switch (ObjectVT) {
307656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    default: assert(0 && "Unhandled argument type!");
308656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    case MVT::i1:
309656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    case MVT::i8:
310656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    case MVT::i16:
311656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    case MVT::i32:
312656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      ObjSize = 4;
313656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      if (!ArgLive) break;
314656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      if (GPR_remaining > 0) {
315656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        MF.addLiveIn(GPR[GPR_idx]);
316656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        argt = newroot = DAG.getCopyFromReg(DAG.getRoot(),
317656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                            GPR[GPR_idx], MVT::i32);
318656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        if (ObjectVT != MVT::i32) {
319656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project          unsigned AssertOp = I->getType()->isSigned() ? ISD::AssertSext
320656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                                       : ISD::AssertZext;
321656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project          argt = DAG.getNode(AssertOp, MVT::i32, argt,
322656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                             DAG.getValueType(ObjectVT));
323656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project          argt = DAG.getNode(ISD::TRUNCATE, ObjectVT, argt);
324656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        }
325656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      } else {
326656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        needsLoad = true;
327656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      }
328656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      break;
329656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    case MVT::i64: ObjSize = 8;
330656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      if (!ArgLive) break;
331656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      if (GPR_remaining > 0) {
332656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        SDOperand argHi, argLo;
333656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        MF.addLiveIn(GPR[GPR_idx]);
334656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        argHi = DAG.getCopyFromReg(DAG.getRoot(), GPR[GPR_idx], MVT::i32);
335656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        // If we have two or more remaining argument registers, then both halves
336656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        // of the i64 can be sourced from there.  Otherwise, the lower half will
337656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        // have to come off the stack.  This can happen when an i64 is preceded
338656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        // by 28 bytes of arguments.
339656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        if (GPR_remaining > 1) {
340656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project          MF.addLiveIn(GPR[GPR_idx+1]);
341656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project          argLo = DAG.getCopyFromReg(argHi, GPR[GPR_idx+1], MVT::i32);
342656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        } else {
343656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project          int FI = MFI->CreateFixedObject(4, ArgOffset+4);
344656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project          SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32);
345656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project          argLo = DAG.getLoad(MVT::i32, DAG.getEntryNode(), FIN,
346656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                              DAG.getSrcValue(NULL));
347656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        }
348656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        // Build the outgoing arg thingy
349656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        argt = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, argLo, argHi);
350656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        newroot = argLo;
351656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      } else {
352656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        needsLoad = true;
353656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      }
354656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      break;
355656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    case MVT::f32:
356656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    case MVT::f64:
357656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      ObjSize = (ObjectVT == MVT::f64) ? 8 : 4;
358656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      if (!ArgLive) break;
359656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      if (FPR_remaining > 0) {
360656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        MF.addLiveIn(FPR[FPR_idx]);
361656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        argt = newroot = DAG.getCopyFromReg(DAG.getRoot(),
362656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                            FPR[FPR_idx], ObjectVT);
363656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        --FPR_remaining;
364656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        ++FPR_idx;
365656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      } else {
366656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        needsLoad = true;
367656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      }
368656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      break;
369656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    }
370656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
371656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    // We need to load the argument to a virtual register if we determined above
372656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    // that we ran out of physical registers of the appropriate type
373656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if (needsLoad) {
374656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      unsigned SubregOffset = 0;
375656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      if (ObjectVT == MVT::i8 || ObjectVT == MVT::i1) SubregOffset = 3;
376656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      if (ObjectVT == MVT::i16) SubregOffset = 2;
377656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      int FI = MFI->CreateFixedObject(ObjSize, ArgOffset);
378656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32);
379656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      FIN = DAG.getNode(ISD::ADD, MVT::i32, FIN,
380656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                        DAG.getConstant(SubregOffset, MVT::i32));
381656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      argt = newroot = DAG.getLoad(ObjectVT, DAG.getEntryNode(), FIN,
382656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                   DAG.getSrcValue(NULL));
383656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    }
384656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
385656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    // Every 4 bytes of argument space consumes one of the GPRs available for
386656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    // argument passing.
387656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if (GPR_remaining > 0) {
388656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      unsigned delta = (GPR_remaining > 1 && ObjSize == 8) ? 2 : 1;
389656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      GPR_remaining -= delta;
390656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      GPR_idx += delta;
391656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    }
392656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    ArgOffset += ObjSize;
393656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if (newroot.Val)
394656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      DAG.setRoot(newroot.getValue(1));
395656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
396656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    ArgValues.push_back(argt);
397656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  }
398656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
399656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // If the function takes variable number of arguments, make a frame index for
400656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // the start of the first vararg value... for expansion of llvm.va_start.
401656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  if (F.isVarArg()) {
402656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    VarArgsFrameIndex = MFI->CreateFixedObject(4, ArgOffset);
403656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand FIN = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32);
404656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    // If this function is vararg, store any remaining integer argument regs
405656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    // to their spots on the stack so that they may be loaded by deferencing the
406656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    // result of va_next.
407656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    std::vector<SDOperand> MemOps;
408656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    for (; GPR_remaining > 0; --GPR_remaining, ++GPR_idx) {
409656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      MF.addLiveIn(GPR[GPR_idx]);
410656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      SDOperand Val = DAG.getCopyFromReg(DAG.getRoot(), GPR[GPR_idx], MVT::i32);
411656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1),
412656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                    Val, FIN, DAG.getSrcValue(NULL));
413656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      MemOps.push_back(Store);
414656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      // Increment the address by four for the next argument to store
415656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      SDOperand PtrOff = DAG.getConstant(4, getPointerTy());
416656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      FIN = DAG.getNode(ISD::ADD, MVT::i32, FIN, PtrOff);
417656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    }
418656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    DAG.setRoot(DAG.getNode(ISD::TokenFactor, MVT::Other, MemOps));
419656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  }
420656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
421656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // Finally, inform the code generator which regs we return values in.
422656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  switch (getValueType(F.getReturnType())) {
423656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    default: assert(0 && "Unknown type!");
424656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    case MVT::isVoid: break;
425656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    case MVT::i1:
426656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    case MVT::i8:
427656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    case MVT::i16:
428656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    case MVT::i32:
429656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      MF.addLiveOut(PPC::R3);
430656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      break;
431656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    case MVT::i64:
432656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      MF.addLiveOut(PPC::R3);
433656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      MF.addLiveOut(PPC::R4);
434656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      break;
435656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    case MVT::f32:
436656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    case MVT::f64:
437656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      MF.addLiveOut(PPC::F1);
438656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      break;
439656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  }
440656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
441656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  return ArgValues;
442656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
443656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
444656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstd::pair<SDOperand, SDOperand>
445656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectPPC32TargetLowering::LowerCallTo(SDOperand Chain,
446656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                 const Type *RetTy, bool isVarArg,
447656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                 unsigned CallingConv, bool isTailCall,
448656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                 SDOperand Callee, ArgListTy &Args,
449656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                 SelectionDAG &DAG) {
450656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // args_to_use will accumulate outgoing args for the ISD::CALL case in
451656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // SelectExpr to use to put the arguments in the appropriate registers.
452656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  std::vector<SDOperand> args_to_use;
453656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
454656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // Count how many bytes are to be pushed on the stack, including the linkage
455656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // area, and parameter passing area.
456656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  unsigned NumBytes = 24;
457656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
458656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  if (Args.empty()) {
459656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    Chain = DAG.getNode(ISD::CALLSEQ_START, MVT::Other, Chain,
460656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                        DAG.getConstant(NumBytes, getPointerTy()));
461656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  } else {
462656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    for (unsigned i = 0, e = Args.size(); i != e; ++i) {
463656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      switch (getValueType(Args[i].second)) {
464656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      default: assert(0 && "Unknown value type!");
465656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      case MVT::i1:
466656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      case MVT::i8:
467656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      case MVT::i16:
468656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      case MVT::i32:
469656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      case MVT::f32:
470656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        NumBytes += 4;
471656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        break;
472656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      case MVT::i64:
473656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      case MVT::f64:
474656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        NumBytes += 8;
475656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        break;
476656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      }
477656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    }
478656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
479656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    // Just to be safe, we'll always reserve the full 24 bytes of linkage area
480656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    // plus 32 bytes of argument space in case any called code gets funky on us.
481656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    // (Required by ABI to support var arg)
482656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if (NumBytes < 56) NumBytes = 56;
483656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
484656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    // Adjust the stack pointer for the new arguments...
485656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    // These operations are automatically eliminated by the prolog/epilog pass
486656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    Chain = DAG.getNode(ISD::CALLSEQ_START, MVT::Other, Chain,
487656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                        DAG.getConstant(NumBytes, getPointerTy()));
488656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
489656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    // Set up a copy of the stack pointer for use loading and storing any
490656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    // arguments that may not fit in the registers available for argument
491656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    // passing.
492656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    SDOperand StackPtr = DAG.getCopyFromReg(DAG.getEntryNode(),
493656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                            PPC::R1, MVT::i32);
494656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
495656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    // Figure out which arguments are going to go in registers, and which in
496656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    // memory.  Also, if this is a vararg function, floating point operations
497656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    // must be stored to our stack, and loaded into integer regs as well, if
498656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    // any integer regs are available for argument passing.
499656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    unsigned ArgOffset = 24;
500656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    unsigned GPR_remaining = 8;
501656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    unsigned FPR_remaining = 13;
502656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
503656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    std::vector<SDOperand> MemOps;
504656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    for (unsigned i = 0, e = Args.size(); i != e; ++i) {
505656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      // PtrOff will be used to store the current argument to the stack if a
506656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      // register cannot be found for it.
507656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy());
508656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff);
509656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      MVT::ValueType ArgVT = getValueType(Args[i].second);
510656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
511656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      switch (ArgVT) {
512656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      default: assert(0 && "Unexpected ValueType for argument!");
513656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      case MVT::i1:
514656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      case MVT::i8:
515656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      case MVT::i16:
516656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        // Promote the integer to 32 bits.  If the input type is signed use a
517656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        // sign extend, otherwise use a zero extend.
518656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        if (Args[i].second->isSigned())
519656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project          Args[i].first =DAG.getNode(ISD::SIGN_EXTEND, MVT::i32, Args[i].first);
520656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        else
521656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project          Args[i].first =DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Args[i].first);
522656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        // FALL THROUGH
523656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      case MVT::i32:
524656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        if (GPR_remaining > 0) {
525656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project          args_to_use.push_back(Args[i].first);
526656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project          --GPR_remaining;
527656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        } else {
528656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project          MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
529656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                       Args[i].first, PtrOff,
530656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                       DAG.getSrcValue(NULL)));
531656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        }
532656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        ArgOffset += 4;
533656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        break;
534656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      case MVT::i64:
535656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        // If we have one free GPR left, we can place the upper half of the i64
536656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        // in it, and store the other half to the stack.  If we have two or more
537656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        // free GPRs, then we can pass both halves of the i64 in registers.
538656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        if (GPR_remaining > 0) {
539656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project          SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32,
540656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                     Args[i].first, DAG.getConstant(1, MVT::i32));
541656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project          SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32,
542656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                     Args[i].first, DAG.getConstant(0, MVT::i32));
543656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project          args_to_use.push_back(Hi);
544656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project          --GPR_remaining;
545656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project          if (GPR_remaining > 0) {
546656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project            args_to_use.push_back(Lo);
547656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project            --GPR_remaining;
548656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project          } else {
549656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project            SDOperand ConstFour = DAG.getConstant(4, getPointerTy());
550656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project            PtrOff = DAG.getNode(ISD::ADD, MVT::i32, PtrOff, ConstFour);
551656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project            MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
552656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                         Lo, PtrOff, DAG.getSrcValue(NULL)));
553656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project          }
554656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        } else {
555656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project          MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
556656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                       Args[i].first, PtrOff,
557656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                       DAG.getSrcValue(NULL)));
558656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        }
559656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        ArgOffset += 8;
560656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        break;
561656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      case MVT::f32:
562656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      case MVT::f64:
563656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        if (FPR_remaining > 0) {
564656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project          args_to_use.push_back(Args[i].first);
565656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project          --FPR_remaining;
566656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project          if (isVarArg) {
567656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project            SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Chain,
568656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                          Args[i].first, PtrOff,
569656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                          DAG.getSrcValue(NULL));
570656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project            MemOps.push_back(Store);
571656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project            // Float varargs are always shadowed in available integer registers
572656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project            if (GPR_remaining > 0) {
573656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project              SDOperand Load = DAG.getLoad(MVT::i32, Store, PtrOff,
574656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                           DAG.getSrcValue(NULL));
575656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project              MemOps.push_back(Load);
576656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project              args_to_use.push_back(Load);
577656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project              --GPR_remaining;
578656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project            }
579656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project            if (GPR_remaining > 0 && MVT::f64 == ArgVT) {
580656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project              SDOperand ConstFour = DAG.getConstant(4, getPointerTy());
581656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project              PtrOff = DAG.getNode(ISD::ADD, MVT::i32, PtrOff, ConstFour);
582656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project              SDOperand Load = DAG.getLoad(MVT::i32, Store, PtrOff,
583656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                           DAG.getSrcValue(NULL));
584656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project              MemOps.push_back(Load);
585656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project              args_to_use.push_back(Load);
586656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project              --GPR_remaining;
587656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project            }
588656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project          } else {
589656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project            // If we have any FPRs remaining, we may also have GPRs remaining.
590656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project            // Args passed in FPRs consume either 1 (f32) or 2 (f64) available
591656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project            // GPRs.
592656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project            if (GPR_remaining > 0) {
593656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project              args_to_use.push_back(DAG.getNode(ISD::UNDEF, MVT::i32));
594656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project              --GPR_remaining;
595656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project            }
596656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project            if (GPR_remaining > 0 && MVT::f64 == ArgVT) {
597656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project              args_to_use.push_back(DAG.getNode(ISD::UNDEF, MVT::i32));
598656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project              --GPR_remaining;
599656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project            }
600656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project          }
601656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        } else {
602656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project          MemOps.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain,
603656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                       Args[i].first, PtrOff,
604656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                       DAG.getSrcValue(NULL)));
605656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        }
606656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        ArgOffset += (ArgVT == MVT::f32) ? 4 : 8;
607656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project        break;
608656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      }
609656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    }
610656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    if (!MemOps.empty())
611656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project      Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, MemOps);
612656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  }
613656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
614656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  std::vector<MVT::ValueType> RetVals;
615656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  MVT::ValueType RetTyVT = getValueType(RetTy);
616656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  if (RetTyVT != MVT::isVoid)
617656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    RetVals.push_back(RetTyVT);
618656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  RetVals.push_back(MVT::Other);
619656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
620656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  SDOperand TheCall = SDOperand(DAG.getCall(RetVals,
621656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                            Chain, Callee, args_to_use), 0);
622656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  Chain = TheCall.getValue(RetTyVT != MVT::isVoid);
623656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, Chain,
624656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                      DAG.getConstant(NumBytes, getPointerTy()));
625656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  return std::make_pair(TheCall, Chain);
626656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
627656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
628656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectSDOperand PPC32TargetLowering::LowerVAStart(SDOperand Chain, SDOperand VAListP,
629656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                            Value *VAListV, SelectionDAG &DAG) {
630656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // vastart just stores the address of the VarArgsFrameIndex slot into the
631656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // memory location argument.
632656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  SDOperand FR = DAG.getFrameIndex(VarArgsFrameIndex, MVT::i32);
633656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  return DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, VAListP,
634656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                     DAG.getSrcValue(VAListV));
635656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
636656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
637656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstd::pair<SDOperand,SDOperand>
638656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectPPC32TargetLowering::LowerVAArg(SDOperand Chain,
639656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                SDOperand VAListP, Value *VAListV,
640656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                const Type *ArgTy, SelectionDAG &DAG) {
641656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  MVT::ValueType ArgVT = getValueType(ArgTy);
642656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
643656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  SDOperand VAList =
644656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    DAG.getLoad(MVT::i32, Chain, VAListP, DAG.getSrcValue(VAListV));
645656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  SDOperand Result = DAG.getLoad(ArgVT, Chain, VAList, DAG.getSrcValue(NULL));
646656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  unsigned Amt;
647656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  if (ArgVT == MVT::i32 || ArgVT == MVT::f32)
648656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    Amt = 4;
649656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  else {
650656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    assert((ArgVT == MVT::i64 || ArgVT == MVT::f64) &&
651656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project           "Other types should have been promoted for varargs!");
652656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    Amt = 8;
653656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  }
654656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  VAList = DAG.getNode(ISD::ADD, VAList.getValueType(), VAList,
655656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                       DAG.getConstant(Amt, VAList.getValueType()));
656656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  Chain = DAG.getNode(ISD::STORE, MVT::Other, Chain,
657656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                      VAList, VAListP, DAG.getSrcValue(VAListV));
658656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  return std::make_pair(Result, Chain);
659656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
660656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
661656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
662656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstd::pair<SDOperand, SDOperand> PPC32TargetLowering::
663656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectLowerFrameReturnAddress(bool isFrameAddress, SDOperand Chain, unsigned Depth,
664656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                        SelectionDAG &DAG) {
665656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  assert(0 && "LowerFrameReturnAddress unimplemented");
666656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  abort();
667656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
668656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
669656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectMachineBasicBlock *
670656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source ProjectPPC32TargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI,
671656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project                                             MachineBasicBlock *BB) {
672656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  assert((MI->getOpcode() == PPC::SELECT_CC_Int ||
673656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project          MI->getOpcode() == PPC::SELECT_CC_FP) &&
674656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project         "Unexpected instr type to insert");
675656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
676656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // To "insert" a SELECT_CC instruction, we actually have to insert the diamond
677656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // control-flow pattern.  The incoming instruction knows the destination vreg
678656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // to set, the condition code register to branch on, the true/false values to
679656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // select between, and a branch opcode to use.
680656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  const BasicBlock *LLVM_BB = BB->getBasicBlock();
681656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  ilist<MachineBasicBlock>::iterator It = BB;
682656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  ++It;
683656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
684656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  //  thisMBB:
685656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  //  ...
686656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  //   TrueVal = ...
687656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  //   cmpTY ccX, r1, r2
688656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  //   bCC copy1MBB
689656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  //   fallthrough --> copy0MBB
690656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  MachineBasicBlock *thisMBB = BB;
691656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB);
692656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB);
693656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  BuildMI(BB, MI->getOperand(4).getImmedValue(), 2)
694656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    .addReg(MI->getOperand(1).getReg()).addMBB(sinkMBB);
695656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  MachineFunction *F = BB->getParent();
696656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  F->getBasicBlockList().insert(It, copy0MBB);
697656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  F->getBasicBlockList().insert(It, sinkMBB);
698656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // Update machine-CFG edges
699656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  BB->addSuccessor(copy0MBB);
700656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  BB->addSuccessor(sinkMBB);
701656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
702656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  //  copy0MBB:
703656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  //   %FalseValue = ...
704656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  //   # fallthrough to sinkMBB
705656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  BB = copy0MBB;
706656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
707656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  // Update machine-CFG edges
708656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  BB->addSuccessor(sinkMBB);
709656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
710656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  //  sinkMBB:
711656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  //   %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ]
712656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  //  ...
713656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  BB = sinkMBB;
714656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  BuildMI(BB, PPC::PHI, 4, MI->getOperand(0).getReg())
715656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    .addReg(MI->getOperand(3).getReg()).addMBB(copy0MBB)
716656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project    .addReg(MI->getOperand(2).getReg()).addMBB(thisMBB);
717656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
718656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  delete MI;   // The pseudo instruction is gone now.
719656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project  return BB;
720656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
721656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
722656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project