static SDValue LowerRETURNADDR(SDValue Op, SelectionDAG &DAG) {
  MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
  MFI->setReturnAddressIsTaken(true);

  EVT VT = Op.getValueType();
  DebugLoc dl = Op.getDebugLoc();
  unsigned RetReg = SP::I7;

  uint64_t depth = Op.getConstantOperandVal(0);

  SDValue RetAddr;
  if (depth == 0)
    RetAddr = DAG.getCopyFromReg(DAG.getEntryNode(), dl, RetReg, VT);
  else {
    // flush first to make sure the windowed registers' values are in stack
    SDValue Chain = getFLUSHW(Op, DAG);
    RetAddr = DAG.getCopyFromReg(Chain, dl, SP::I6, VT);

    for (uint64_t i = 0; i != depth; ++i) {
      SDValue Ptr = DAG.getNode(ISD::ADD,
                                dl, MVT::i32,
                                RetAddr,
                                DAG.getIntPtrConstant((i == depth-1)?60:56));
      RetAddr = DAG.getLoad(MVT::i32, dl,
                            Chain,
                            Ptr,
                            MachinePointerInfo(), false, false, 0);
    }
  }
  return RetAddr;
}
SDValue WebAssemblyTargetLowering::LowerFRAMEADDR(SDValue Op,
                                                  SelectionDAG &DAG) const {
  // Non-zero depths are not supported by WebAssembly currently. Use the
  // legalizer's default expansion, which is to return 0 (what this function is
  // documented to do).
  if (Op.getConstantOperandVal(0) > 0)
    return SDValue();

  DAG.getMachineFunction().getFrameInfo()->setFrameAddressIsTaken(true);
  EVT VT = Op.getValueType();
  unsigned FP =
      Subtarget->getRegisterInfo()->getFrameRegister(DAG.getMachineFunction());
  return DAG.getCopyFromReg(DAG.getEntryNode(), SDLoc(Op), FP, VT);
}