Пример #1
0
static void writeSPToMemory(unsigned SrcReg, MachineFunction &MF,
                            MachineBasicBlock &MBB,
                            MachineBasicBlock::iterator &InsertAddr,
                            MachineBasicBlock::iterator &InsertStore,
                            const DebugLoc &DL) {
    const char *ES = "__stack_pointer";
    auto *SPSymbol = MF.createExternalSymbolName(ES);
    MachineRegisterInfo &MRI = MF.getRegInfo();
    const TargetRegisterClass *PtrRC =
        MRI.getTargetRegisterInfo()->getPointerRegClass(MF);
    unsigned Zero = MRI.createVirtualRegister(PtrRC);
    const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();

    BuildMI(MBB, InsertAddr, DL, TII->get(WebAssembly::CONST_I32), Zero)
    .addImm(0);
    MachineMemOperand *MMO = MF.getMachineMemOperand(
                                 MachinePointerInfo(MF.getPSVManager().getExternalSymbolCallEntry(ES)),
                                 MachineMemOperand::MOStore, 4, 4);
    BuildMI(MBB, InsertStore, DL, TII->get(WebAssembly::STORE_I32))
    .addImm(2)  // p2align
    .addExternalSymbol(SPSymbol)
    .addReg(Zero)
    .addReg(SrcReg)
    .addMemOperand(MMO);
}
Пример #2
0
void WebAssemblyFrameLowering::emitEpilogue(MachineFunction &MF,
                                            MachineBasicBlock &MBB) const {
  uint64_t StackSize = MF.getFrameInfo()->getStackSize();
  if (!StackSize)
    return;
  const auto *TII = MF.getSubtarget().getInstrInfo();
  auto &MRI = MF.getRegInfo();
  unsigned OffsetReg = MRI.createVirtualRegister(&WebAssembly::I32RegClass);
  auto InsertPt = MBB.getFirstTerminator();
  DebugLoc DL;

  if (InsertPt != MBB.end()) {
    DL = InsertPt->getDebugLoc();
  }

  // Restore the stack pointer. Without FP its value is just SP32 - stacksize
  BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::CONST_I32), OffsetReg)
      .addImm(StackSize);
  auto *SPSymbol = MF.createExternalSymbolName("__stack_pointer");
  BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::ADD_I32), WebAssembly::SP32)
      .addReg(WebAssembly::SP32)
      .addReg(OffsetReg);
  // Re-use OffsetReg to hold the address of the stacktop
  BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::CONST_I32), OffsetReg)
      .addExternalSymbol(SPSymbol);
  auto *MMO = new MachineMemOperand(MachinePointerInfo(),
                                    MachineMemOperand::MOStore, 4, 4);
  BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::STORE_I32), WebAssembly::SP32)
      .addImm(0)
      .addReg(OffsetReg)
      .addReg(WebAssembly::SP32)
      .addMemOperand(MMO);
}
Пример #3
0
void WebAssemblyFrameLowering::emitPrologue(MachineFunction &MF,
        MachineBasicBlock &MBB) const {
    // TODO: Do ".setMIFlag(MachineInstr::FrameSetup)" on emitted instructions
    auto &MFI = MF.getFrameInfo();
    assert(MFI.getCalleeSavedInfo().empty() &&
           "WebAssembly should not have callee-saved registers");

    if (!needsSP(MF, MFI)) return;
    uint64_t StackSize = MFI.getStackSize();

    const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
    auto &MRI = MF.getRegInfo();

    auto InsertPt = MBB.begin();
    DebugLoc DL;

    const TargetRegisterClass *PtrRC =
        MRI.getTargetRegisterInfo()->getPointerRegClass(MF);
    unsigned Zero = MRI.createVirtualRegister(PtrRC);
    unsigned SPReg = MRI.createVirtualRegister(PtrRC);
    const char *ES = "__stack_pointer";
    auto *SPSymbol = MF.createExternalSymbolName(ES);
    BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::CONST_I32), Zero)
    .addImm(0);
    MachineMemOperand *LoadMMO = MF.getMachineMemOperand(
                                     MachinePointerInfo(MF.getPSVManager().getExternalSymbolCallEntry(ES)),
                                     MachineMemOperand::MOLoad, 4, 4);
    // Load the SP value.
    BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::LOAD_I32),
            StackSize ? SPReg : (unsigned)WebAssembly::SP32)
    .addImm(2)       // p2align
    .addExternalSymbol(SPSymbol)
    .addReg(Zero)    // addr
    .addMemOperand(LoadMMO);

    if (StackSize) {
        // Subtract the frame size
        unsigned OffsetReg = MRI.createVirtualRegister(PtrRC);
        BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::CONST_I32), OffsetReg)
        .addImm(StackSize);
        BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::SUB_I32),
                WebAssembly::SP32)
        .addReg(SPReg)
        .addReg(OffsetReg);
    }
    if (hasFP(MF)) {
        // Unlike most conventional targets (where FP points to the saved FP),
        // FP points to the bottom of the fixed-size locals, so we can use positive
        // offsets in load/store instructions.
        BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::COPY),
                WebAssembly::FP32)
        .addReg(WebAssembly::SP32);
    }
    if (StackSize && needsSPWriteback(MF, MFI)) {
        writeSPToMemory(WebAssembly::SP32, MF, MBB, InsertPt, InsertPt, DL);
    }
}
static void writeSPToMemory(unsigned SrcReg, MachineFunction &MF,
                            MachineBasicBlock &MBB,
                            MachineBasicBlock::iterator &InsertAddr,
                            MachineBasicBlock::iterator &InsertStore,
                            const DebugLoc &DL) {
  const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();

  const char *ES = "__stack_pointer";
  auto *SPSymbol = MF.createExternalSymbolName(ES);
  BuildMI(MBB, InsertStore, DL, TII->get(WebAssembly::SET_GLOBAL_I32))
      .addExternalSymbol(SPSymbol)
      .addReg(SrcReg);
}
Пример #5
0
/// Adjust the stack pointer by a constant amount.
static void adjustStackPointer(unsigned StackSize,
                               bool AdjustUp,
                               MachineFunction& MF,
                               MachineBasicBlock& MBB,
                               const TargetInstrInfo* TII,
                               MachineBasicBlock::iterator InsertPt,
                               const DebugLoc& DL) {
  auto &MRI = MF.getRegInfo();
  unsigned SPReg = MRI.createVirtualRegister(&WebAssembly::I32RegClass);
  auto *SPSymbol = MF.createExternalSymbolName("__stack_pointer");
  BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::CONST_I32), SPReg)
      .addExternalSymbol(SPSymbol);
  // This MachinePointerInfo should reference __stack_pointer as well but
  // doesn't because MachinePointerInfo() takes a GV which we don't have for
  // __stack_pointer. TODO: check if PseudoSourceValue::ExternalSymbolCallEntry
  // is appropriate instead. (likewise for EmitEpologue below)
  auto *LoadMMO = new MachineMemOperand(MachinePointerInfo(),
                                        MachineMemOperand::MOLoad, 4, 4);
  BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::LOAD_I32), SPReg)
      .addImm(0)
      .addReg(SPReg)
      .addImm(2) // p2align
      .addMemOperand(LoadMMO);
  // Add/Subtract the frame size
  unsigned OffsetReg = MRI.createVirtualRegister(&WebAssembly::I32RegClass);
  BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::CONST_I32), OffsetReg)
      .addImm(StackSize);
  BuildMI(MBB, InsertPt, DL,
          TII->get(AdjustUp ? WebAssembly::ADD_I32 : WebAssembly::SUB_I32),
          WebAssembly::SP32)
      .addReg(SPReg)
      .addReg(OffsetReg);
  // The SP32 register now has the new stacktop. Also write it back to memory.
  BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::CONST_I32), OffsetReg)
      .addExternalSymbol(SPSymbol);
  auto *MMO = new MachineMemOperand(MachinePointerInfo(),
                                    MachineMemOperand::MOStore, 4, 4);
  BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::STORE_I32), WebAssembly::SP32)
      .addImm(0)
      .addReg(OffsetReg)
      .addImm(2) // p2align
      .addReg(WebAssembly::SP32)
      .addMemOperand(MMO);
}
Пример #6
0
static void writeSPToMemory(unsigned SrcReg, MachineFunction &MF,
                            MachineBasicBlock &MBB,
                            MachineBasicBlock::iterator &InsertAddr,
                            MachineBasicBlock::iterator &InsertStore,
                            DebugLoc DL) {
  auto *SPSymbol = MF.createExternalSymbolName("__stack_pointer");
  unsigned SPAddr =
      MF.getRegInfo().createVirtualRegister(&WebAssembly::I32RegClass);
  const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();

  BuildMI(MBB, InsertAddr, DL, TII->get(WebAssembly::CONST_I32), SPAddr)
      .addExternalSymbol(SPSymbol);
  auto *MMO = new MachineMemOperand(MachinePointerInfo(),
                                    MachineMemOperand::MOStore, 4, 4);
  BuildMI(MBB, InsertStore, DL, TII->get(WebAssembly::STORE_I32),
          SrcReg)
      .addImm(0)
      .addReg(SPAddr)
      .addImm(2)  // p2align
      .addReg(SrcReg)
      .addMemOperand(MMO);
  MF.getInfo<WebAssemblyFunctionInfo>()->stackifyVReg(SPAddr);
}
void WebAssemblyFrameLowering::emitPrologue(MachineFunction &MF,
                                            MachineBasicBlock &MBB) const {
  // TODO: Do ".setMIFlag(MachineInstr::FrameSetup)" on emitted instructions
  auto &MFI = MF.getFrameInfo();
  assert(MFI.getCalleeSavedInfo().empty() &&
         "WebAssembly should not have callee-saved registers");

  if (!needsSP(MF, MFI)) return;
  uint64_t StackSize = MFI.getStackSize();

  const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
  auto &MRI = MF.getRegInfo();

  auto InsertPt = MBB.begin();
  while (InsertPt != MBB.end() && WebAssembly::isArgument(*InsertPt))
    ++InsertPt;
  DebugLoc DL;

  const TargetRegisterClass *PtrRC =
      MRI.getTargetRegisterInfo()->getPointerRegClass(MF);
  unsigned SPReg = WebAssembly::SP32;
  if (StackSize)
    SPReg = MRI.createVirtualRegister(PtrRC);

  const char *ES = "__stack_pointer";
  auto *SPSymbol = MF.createExternalSymbolName(ES);
  if (MF.getSubtarget<WebAssemblySubtarget>()
        .getTargetTriple().isOSBinFormatELF()) {
    unsigned Zero = MRI.createVirtualRegister(PtrRC);

    BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::CONST_I32), Zero)
        .addImm(0);
    MachineMemOperand *LoadMMO = MF.getMachineMemOperand(
        MachinePointerInfo(MF.getPSVManager().getExternalSymbolCallEntry(ES)),
        MachineMemOperand::MOLoad, 4, 4);
    // Load the SP value.
    BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::LOAD_I32), SPReg)
        .addImm(2)       // p2align
        .addExternalSymbol(SPSymbol)
        .addReg(Zero)    // addr
        .addMemOperand(LoadMMO);
  } else {
    BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::GET_GLOBAL_I32), SPReg)
        .addExternalSymbol(SPSymbol);
  }

  bool HasBP = hasBP(MF);
  if (HasBP) {
    auto FI = MF.getInfo<WebAssemblyFunctionInfo>();
    unsigned BasePtr = MRI.createVirtualRegister(PtrRC);
    FI->setBasePointerVreg(BasePtr);
    BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::COPY), BasePtr)
        .addReg(SPReg);
  }
  if (StackSize) {
    // Subtract the frame size
    unsigned OffsetReg = MRI.createVirtualRegister(PtrRC);
    BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::CONST_I32), OffsetReg)
        .addImm(StackSize);
    BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::SUB_I32),
            WebAssembly::SP32)
        .addReg(SPReg)
        .addReg(OffsetReg);
  }
  if (HasBP) {
    unsigned BitmaskReg = MRI.createVirtualRegister(PtrRC);
    unsigned Alignment = MFI.getMaxAlignment();
    assert((1u << countTrailingZeros(Alignment)) == Alignment &&
      "Alignment must be a power of 2");
    BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::CONST_I32), BitmaskReg)
        .addImm((int)~(Alignment - 1));
    BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::AND_I32),
            WebAssembly::SP32)
        .addReg(WebAssembly::SP32)
        .addReg(BitmaskReg);
  }
  if (hasFP(MF)) {
    // Unlike most conventional targets (where FP points to the saved FP),
    // FP points to the bottom of the fixed-size locals, so we can use positive
    // offsets in load/store instructions.
    BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::COPY),
            WebAssembly::FP32)
        .addReg(WebAssembly::SP32);
  }
  if (StackSize && needsSPWriteback(MF, MFI)) {
    writeSPToMemory(WebAssembly::SP32, MF, MBB, InsertPt, InsertPt, DL);
  }
}
Пример #8
0
void WebAssemblyFrameLowering::emitPrologue(MachineFunction &MF,
                                            MachineBasicBlock &MBB) const {
  // TODO: Do ".setMIFlag(MachineInstr::FrameSetup)" on emitted instructions
  auto *MFI = MF.getFrameInfo();
  assert(MFI->getCalleeSavedInfo().empty() &&
         "WebAssembly should not have callee-saved registers");
  auto *WFI = MF.getInfo<WebAssemblyFunctionInfo>();

  if (!needsSP(MF, *MFI)) return;
  uint64_t StackSize = MFI->getStackSize();

  const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
  auto &MRI = MF.getRegInfo();

  auto InsertPt = MBB.begin();
  DebugLoc DL;

  unsigned SPAddr = MRI.createVirtualRegister(&WebAssembly::I32RegClass);
  unsigned SPReg = MRI.createVirtualRegister(&WebAssembly::I32RegClass);
  auto *SPSymbol = MF.createExternalSymbolName("__stack_pointer");
  BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::CONST_I32), SPAddr)
      .addExternalSymbol(SPSymbol);
  // This MachinePointerInfo should reference __stack_pointer as well but
  // doesn't because MachinePointerInfo() takes a GV which we don't have for
  // __stack_pointer. TODO: check if PseudoSourceValue::ExternalSymbolCallEntry
  // is appropriate instead. (likewise for EmitEpologue below)
  auto *LoadMMO = new MachineMemOperand(MachinePointerInfo(),
                                        MachineMemOperand::MOLoad, 4, 4);
  // Load the SP value.
  BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::LOAD_I32),
          StackSize ? SPReg : (unsigned)WebAssembly::SP32)
      .addImm(0)       // offset
      .addReg(SPAddr)  // addr
      .addImm(2)       // p2align
      .addMemOperand(LoadMMO);
  WFI->stackifyVReg(SPAddr);

  if (StackSize) {
    // Subtract the frame size
    unsigned OffsetReg = MRI.createVirtualRegister(&WebAssembly::I32RegClass);
    BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::CONST_I32), OffsetReg)
        .addImm(StackSize);
    BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::SUB_I32),
            WebAssembly::SP32)
        .addReg(SPReg)
        .addReg(OffsetReg);
    WFI->stackifyVReg(OffsetReg);
    WFI->stackifyVReg(SPReg);
  }
  if (hasFP(MF)) {
    // Unlike most conventional targets (where FP points to the saved FP),
    // FP points to the bottom of the fixed-size locals, so we can use positive
    // offsets in load/store instructions.
    BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::COPY_LOCAL_I32),
            WebAssembly::FP32)
        .addReg(WebAssembly::SP32);
  }
  if (StackSize && needsSPWriteback(MF, *MFI)) {
    writeSPToMemory(WebAssembly::SP32, MF, MBB, InsertPt, InsertPt, DL);
  }
}