diff options
Diffstat (limited to 'llvm/lib/Target')
-rw-r--r-- | llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp | 11 | ||||
-rw-r--r-- | llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp | 20 |
2 files changed, 25 insertions, 6 deletions
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp index 211358ad66c..ee60c8f3a7a 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyAsmPrinter.cpp @@ -267,12 +267,11 @@ bool WebAssemblyAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, if (AsmVariant != 0) report_fatal_error("There are no defined alternate asm variants"); - if (!ExtraCode) { - // TODO: For now, we just hard-code 0 as the constant offset; teach - // SelectInlineAsmMemoryOperand how to do address mode matching. - OS << "0(" + regToString(MI->getOperand(OpNo)) + ')'; - return false; - } + // The current approach to inline asm is that "r" constraints are expressed + // as local indices, rather than values on the operand stack. This simplifies + // using "r" as it eliminates the need to push and pop the values in a + // particular order, however it also makes it impossible to have an "m" + // constraint. So we don't support it. return AsmPrinter::PrintAsmMemoryOperand(MI, OpNo, AsmVariant, ExtraCode, OS); } diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp index 41249117ae0..e2edb924d4d 100644 --- a/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp +++ b/llvm/lib/Target/WebAssembly/WebAssemblyExplicitLocals.cpp @@ -294,6 +294,17 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) { unsigned OldReg = MO.getReg(); + // Inline asm may have a def in the middle of the operands. Our contract + // with inline asm register operands is to provide local indices as + // immediates. + if (MO.isDef()) { + assert(MI.getOpcode() == TargetOpcode::INLINEASM); + unsigned LocalId = getLocalId(Reg2Local, CurLocal, OldReg); + MRI.removeRegOperandFromUseList(&MO); + MO = MachineOperand::CreateImm(LocalId); + continue; + } + // If we see a stackified register, prepare to insert subsequent // get_locals before the start of its tree. if (MFI.isVRegStackified(OldReg)) { @@ -301,6 +312,15 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) { continue; } + // Our contract with inline asm register operands is to provide local + // indices as immediates. + if (MI.getOpcode() == TargetOpcode::INLINEASM) { + unsigned LocalId = getLocalId(Reg2Local, CurLocal, OldReg); + MRI.removeRegOperandFromUseList(&MO); + MO = MachineOperand::CreateImm(LocalId); + continue; + } + // Insert a get_local. unsigned LocalId = getLocalId(Reg2Local, CurLocal, OldReg); const TargetRegisterClass *RC = MRI.getRegClass(OldReg); |