aardappel updated this revision to Diff 271859.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D82130/new/
https://reviews.llvm.org/D82130
Files:
clang/lib/Driver/ToolChains/WebAssembly.cpp
lld/wasm/Config.h
lld/wasm/Driver.cpp
lld/wasm/InputChunks.cpp
lld/wasm/Options.td
llvm/include/llvm/BinaryFormat/Wasm.h
llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp
llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.h
llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp
llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp
llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp
llvm/test/MC/WebAssembly/stack-ptr.ll
llvm/test/MC/WebAssembly/wasm64.s
Index: llvm/test/MC/WebAssembly/wasm64.s
===================================================================
--- llvm/test/MC/WebAssembly/wasm64.s
+++ llvm/test/MC/WebAssembly/wasm64.s
@@ -51,6 +51,11 @@
i64.const 0
f32.store .L.str # relocatable offset!
+ ### 64-bit SP
+
+ global.get __stack_pointer
+ drop
+
end_function
.section .rodata..L.str,"",@
@@ -62,7 +67,7 @@
.size .L.str, 24
.globaltype myglob64, i64
-
+ .globaltype __stack_pointer, i64
# CHECK: .functype test (i64) -> ()
@@ -155,6 +160,11 @@
# BIN-NEXT: Kind: GLOBAL
# BIN-NEXT: GlobalType: I64
# BIN-NEXT: GlobalMutable: true
+# BIN-NEXT: - Module: env
+# BIN-NEXT: Field: __stack_pointer
+# BIN-NEXT: Kind: GLOBAL
+# BIN-NEXT: GlobalType: I64
+# BIN-NEXT: GlobalMutable: true
# BIN-NEXT: - Type: FUNCTION
# BIN-NEXT: FunctionTypes: [ 0 ]
# BIN-NEXT: - Type: DATACOUNT
@@ -179,12 +189,15 @@
# BIN-NEXT: - Type: R_WASM_MEMORY_ADDR_LEB64
# BIN-NEXT: Index: 1
# BIN-NEXT: Offset: 0x00000078
+# BIN-NEXT: - Type: R_WASM_GLOBAL_INDEX_LEB
+# BIN-NEXT: Index: 3
+# BIN-NEXT: Offset: 0x00000083
# BIN-NEXT: Functions:
# BIN-NEXT: - Index: 0
# BIN-NEXT: Locals:
# BIN-NEXT: - Type: I64
# BIN-NEXT: Count: 1
-# BIN-NEXT: Body: 42002A02001A20002A02001A42808080808080808080002A02001A2380808080002A02001A42002A02808080808080808080001A4300000000420038020043000000002000380200430000000042808080808080808080003802004300000000238080808000380200430000000042003802808080808080808080000B
+# BIN-NEXT: Body: 42002A02001A20002A02001A42808080808080808080002A02001A2380808080002A02001A42002A02808080808080808080001A4300000000420038020043000000002000380200430000000042808080808080808080003802004300000000238080808000380200430000000042003802808080808080808080002381808080001A0B
# BIN-NEXT: - Type: DATA
# BIN-NEXT: Relocations:
# BIN-NEXT: - Type: R_WASM_MEMORY_ADDR_I64
@@ -217,6 +230,11 @@
# BIN-NEXT: Name: myglob64
# BIN-NEXT: Flags: [ UNDEFINED ]
# BIN-NEXT: Global: 0
+# BIN-NEXT: - Index: 3
+# BIN-NEXT: Kind: GLOBAL
+# BIN-NEXT: Name: __stack_pointer
+# BIN-NEXT: Flags: [ UNDEFINED ]
+# BIN-NEXT: Global: 1
# BIN-NEXT: SegmentInfo:
# BIN-NEXT: - Index: 0
# BIN-NEXT: Name: .rodata..L.str
Index: llvm/test/MC/WebAssembly/stack-ptr.ll
===================================================================
--- llvm/test/MC/WebAssembly/stack-ptr.ll
+++ llvm/test/MC/WebAssembly/stack-ptr.ll
@@ -1,6 +1,5 @@
-; RUN: llc -filetype=obj %s -o - | obj2yaml | FileCheck %s
-
-target triple = "wasm32-unknown-unknown"
+; RUN: llc --mtriple=wasm32-unknown-unknown -filetype=obj %s -o - | obj2yaml | FileCheck --check-prefixes CHECK,CHK32 %s
+; RUN: llc --mtriple=wasm64-unknown-unknown -filetype=obj %s -o - | obj2yaml | FileCheck --check-prefixes CHECK,CHK64 %s
; Function that uses explict stack, and should generate a reference to
; __stack_pointer, along with the corresponding reloction entry.
@@ -15,7 +14,8 @@
; CHECK: - Module: env
; CHECK: Field: __stack_pointer
; CHECK: Kind: GLOBAL
-; CHECK: GlobalType: I32
+; CHK32: GlobalType: I32
+; CHK64: GlobalType: I64
; CHECK: GlobalMutable: true
; CHECK: - Type: CODE
; CHECK: Relocations:
Index: llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyRegStackify.cpp
@@ -248,7 +248,8 @@
}
// Check for writes to __stack_pointer global.
- if (MI.getOpcode() == WebAssembly::GLOBAL_SET_I32 &&
+ if ((MI.getOpcode() == WebAssembly::GLOBAL_SET_I32 ||
+ MI.getOpcode() == WebAssembly::GLOBAL_SET_I64) &&
strcmp(MI.getOperand(0).getSymbolName(), "__stack_pointer") == 0)
StackPointer = true;
Index: llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyMCInstLower.cpp
@@ -81,8 +81,9 @@
strcmp(Name, "__stack_pointer") == 0 || strcmp(Name, "__tls_base") == 0;
WasmSym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL);
WasmSym->setGlobalType(wasm::WasmGlobalType{
- uint8_t(Subtarget.hasAddr64() ? wasm::WASM_TYPE_I64
- : wasm::WASM_TYPE_I32),
+ uint8_t(Subtarget.hasAddr64() && strcmp(Name, "__table_base") != 0
+ ? wasm::WASM_TYPE_I64
+ : wasm::WASM_TYPE_I32),
Mutable});
return WasmSym;
}
Index: llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyLateEHPrepare.cpp
@@ -408,8 +408,8 @@
++InsertPos;
if (InsertPos->getOpcode() == WebAssembly::CATCH)
++InsertPos;
- FrameLowering->writeSPToGlobal(WebAssembly::SP32, MF, MBB, InsertPos,
- MBB.begin()->getDebugLoc());
+ FrameLowering->writeSPToGlobal(FrameLowering->getSPReg(MF), MF, MBB,
+ InsertPos, MBB.begin()->getDebugLoc());
}
return Changed;
}
Index: llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyISelDAGToDAG.cpp
@@ -77,6 +77,13 @@
return;
}
+ MVT PtrVT = TLI->getPointerTy(CurDAG->getDataLayout());
+ auto GlobalGetIns = PtrVT == MVT::i64 ? WebAssembly::GLOBAL_GET_I64
+ : WebAssembly::GLOBAL_GET_I32;
+ auto ConstIns =
+ PtrVT == MVT::i64 ? WebAssembly::CONST_I64 : WebAssembly::CONST_I32;
+ auto AddIns = PtrVT == MVT::i64 ? WebAssembly::ADD_I64 : WebAssembly::ADD_I32;
+
// Few custom selection stuff.
SDLoc DL(Node);
MachineFunction &MF = CurDAG->getMachineFunction();
@@ -140,20 +147,16 @@
false);
}
- MVT PtrVT = TLI->getPointerTy(CurDAG->getDataLayout());
- assert(PtrVT == MVT::i32 && "only wasm32 is supported for now");
-
SDValue TLSBaseSym = CurDAG->getTargetExternalSymbol("__tls_base", PtrVT);
SDValue TLSOffsetSym = CurDAG->getTargetGlobalAddress(
GA->getGlobal(), DL, PtrVT, GA->getOffset(), 0);
- MachineSDNode *TLSBase = CurDAG->getMachineNode(WebAssembly::GLOBAL_GET_I32,
- DL, MVT::i32, TLSBaseSym);
- MachineSDNode *TLSOffset = CurDAG->getMachineNode(
- WebAssembly::CONST_I32, DL, MVT::i32, TLSOffsetSym);
- MachineSDNode *TLSAddress =
- CurDAG->getMachineNode(WebAssembly::ADD_I32, DL, MVT::i32,
- SDValue(TLSBase, 0), SDValue(TLSOffset, 0));
+ MachineSDNode *TLSBase =
+ CurDAG->getMachineNode(GlobalGetIns, DL, PtrVT, TLSBaseSym);
+ MachineSDNode *TLSOffset =
+ CurDAG->getMachineNode(ConstIns, DL, PtrVT, TLSOffsetSym);
+ MachineSDNode *TLSAddress = CurDAG->getMachineNode(
+ AddIns, DL, PtrVT, SDValue(TLSBase, 0), SDValue(TLSOffset, 0));
ReplaceNode(Node, TLSAddress);
return;
}
@@ -162,22 +165,16 @@
unsigned IntNo = cast<ConstantSDNode>(Node->getOperand(0))->getZExtValue();
switch (IntNo) {
case Intrinsic::wasm_tls_size: {
- MVT PtrVT = TLI->getPointerTy(CurDAG->getDataLayout());
- assert(PtrVT == MVT::i32 && "only wasm32 is supported for now");
-
MachineSDNode *TLSSize = CurDAG->getMachineNode(
- WebAssembly::GLOBAL_GET_I32, DL, PtrVT,
- CurDAG->getTargetExternalSymbol("__tls_size", MVT::i32));
+ GlobalGetIns, DL, PtrVT,
+ CurDAG->getTargetExternalSymbol("__tls_size", PtrVT));
ReplaceNode(Node, TLSSize);
return;
}
case Intrinsic::wasm_tls_align: {
- MVT PtrVT = TLI->getPointerTy(CurDAG->getDataLayout());
- assert(PtrVT == MVT::i32 && "only wasm32 is supported for now");
-
MachineSDNode *TLSAlign = CurDAG->getMachineNode(
- WebAssembly::GLOBAL_GET_I32, DL, PtrVT,
- CurDAG->getTargetExternalSymbol("__tls_align", MVT::i32));
+ GlobalGetIns, DL, PtrVT,
+ CurDAG->getTargetExternalSymbol("__tls_align", PtrVT));
ReplaceNode(Node, TLSAlign);
return;
}
@@ -188,11 +185,8 @@
unsigned IntNo = cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue();
switch (IntNo) {
case Intrinsic::wasm_tls_base: {
- MVT PtrVT = TLI->getPointerTy(CurDAG->getDataLayout());
- assert(PtrVT == MVT::i32 && "only wasm32 is supported for now");
-
MachineSDNode *TLSBase = CurDAG->getMachineNode(
- WebAssembly::GLOBAL_GET_I32, DL, MVT::i32, MVT::Other,
+ GlobalGetIns, DL, PtrVT, MVT::Other,
CurDAG->getTargetExternalSymbol("__tls_base", PtrVT),
Node->getOperand(0));
ReplaceNode(Node, TLSBase);
Index: llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.h
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.h
+++ llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.h
@@ -53,6 +53,15 @@
MachineBasicBlock::iterator &InsertStore,
const DebugLoc &DL) const;
+ unsigned getSPReg(const MachineFunction &MF) const;
+ unsigned getFPReg(const MachineFunction &MF) const;
+ unsigned getOpcConst(const MachineFunction &MF) const;
+ unsigned getOpcAdd(const MachineFunction &MF) const;
+ unsigned getOpcSub(const MachineFunction &MF) const;
+ unsigned getOpcAnd(const MachineFunction &MF) const;
+ unsigned getOpcGlobGet(const MachineFunction &MF) const;
+ unsigned getOpcGlobSet(const MachineFunction &MF) const;
+
private:
bool hasBP(const MachineFunction &MF) const;
bool needsSPForLocalFrame(const MachineFunction &MF) const;
Index: llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp
===================================================================
--- llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp
+++ llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp
@@ -87,8 +87,8 @@
}
// In function with EH pads, we need to make a copy of the value of
-// __stack_pointer global in SP32 register, in order to use it when restoring
-// __stack_pointer after an exception is caught.
+// __stack_pointer global in SP32/64 register, in order to use it when
+// restoring __stack_pointer after an exception is caught.
bool WebAssemblyFrameLowering::needsPrologForEH(
const MachineFunction &MF) const {
auto EHType = MF.getTarget().getMCAsmInfo()->getExceptionHandlingType();
@@ -123,6 +123,57 @@
return needsSPForLocalFrame(MF) && !CanUseRedZone;
}
+unsigned WebAssemblyFrameLowering::getSPReg(const MachineFunction &MF) const {
+ return MF.getSubtarget<WebAssemblySubtarget>().hasAddr64()
+ ? WebAssembly::SP64
+ : WebAssembly::SP32;
+}
+
+unsigned WebAssemblyFrameLowering::getFPReg(const MachineFunction &MF) const {
+ return MF.getSubtarget<WebAssemblySubtarget>().hasAddr64()
+ ? WebAssembly::FP64
+ : WebAssembly::FP32;
+}
+
+unsigned
+WebAssemblyFrameLowering::getOpcConst(const MachineFunction &MF) const {
+ return MF.getSubtarget<WebAssemblySubtarget>().hasAddr64()
+ ? WebAssembly::CONST_I64
+ : WebAssembly::CONST_I32;
+}
+
+unsigned WebAssemblyFrameLowering::getOpcAdd(const MachineFunction &MF) const {
+ return MF.getSubtarget<WebAssemblySubtarget>().hasAddr64()
+ ? WebAssembly::ADD_I64
+ : WebAssembly::ADD_I32;
+}
+
+unsigned WebAssemblyFrameLowering::getOpcSub(const MachineFunction &MF) const {
+ return MF.getSubtarget<WebAssemblySubtarget>().hasAddr64()
+ ? WebAssembly::SUB_I64
+ : WebAssembly::SUB_I32;
+}
+
+unsigned WebAssemblyFrameLowering::getOpcAnd(const MachineFunction &MF) const {
+ return MF.getSubtarget<WebAssemblySubtarget>().hasAddr64()
+ ? WebAssembly::AND_I64
+ : WebAssembly::AND_I32;
+}
+
+unsigned
+WebAssemblyFrameLowering::getOpcGlobGet(const MachineFunction &MF) const {
+ return MF.getSubtarget<WebAssemblySubtarget>().hasAddr64()
+ ? WebAssembly::GLOBAL_GET_I64
+ : WebAssembly::GLOBAL_GET_I32;
+}
+
+unsigned
+WebAssemblyFrameLowering::getOpcGlobSet(const MachineFunction &MF) const {
+ return MF.getSubtarget<WebAssemblySubtarget>().hasAddr64()
+ ? WebAssembly::GLOBAL_SET_I64
+ : WebAssembly::GLOBAL_SET_I32;
+}
+
void WebAssemblyFrameLowering::writeSPToGlobal(
unsigned SrcReg, MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator &InsertStore, const DebugLoc &DL) const {
@@ -130,7 +181,8 @@
const char *ES = "__stack_pointer";
auto *SPSymbol = MF.createExternalSymbolName(ES);
- BuildMI(MBB, InsertStore, DL, TII->get(WebAssembly::GLOBAL_SET_I32))
+
+ BuildMI(MBB, InsertStore, DL, TII->get(getOpcGlobSet(MF)))
.addExternalSymbol(SPSymbol)
.addReg(SrcReg);
}
@@ -141,11 +193,12 @@
MachineBasicBlock::iterator I) const {
assert(!I->getOperand(0).getImm() && (hasFP(MF) || hasBP(MF)) &&
"Call frame pseudos should only be used for dynamic stack adjustment");
- const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
+ auto &ST = MF.getSubtarget<WebAssemblySubtarget>();
+ const auto *TII = ST.getInstrInfo();
if (I->getOpcode() == TII->getCallFrameDestroyOpcode() &&
needsSPWriteback(MF)) {
DebugLoc DL = I->getDebugLoc();
- writeSPToGlobal(WebAssembly::SP32, MF, MBB, I, DL);
+ writeSPToGlobal(getSPReg(MF), MF, MBB, I, DL);
}
return MBB.erase(I);
}
@@ -161,7 +214,8 @@
return;
uint64_t StackSize = MFI.getStackSize();
- const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
+ auto &ST = MF.getSubtarget<WebAssemblySubtarget>();
+ const auto *TII = ST.getInstrInfo();
auto &MRI = MF.getRegInfo();
auto InsertPt = MBB.begin();
@@ -172,13 +226,13 @@
const TargetRegisterClass *PtrRC =
MRI.getTargetRegisterInfo()->getPointerRegClass(MF);
- unsigned SPReg = WebAssembly::SP32;
+ unsigned SPReg = getSPReg(MF);
if (StackSize)
SPReg = MRI.createVirtualRegister(PtrRC);
const char *ES = "__stack_pointer";
auto *SPSymbol = MF.createExternalSymbolName(ES);
- BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::GLOBAL_GET_I32), SPReg)
+ BuildMI(MBB, InsertPt, DL, TII->get(getOpcGlobGet(MF)), SPReg)
.addExternalSymbol(SPSymbol);
bool HasBP = hasBP(MF);
@@ -192,32 +246,30 @@
if (StackSize) {
// Subtract the frame size
Register OffsetReg = MRI.createVirtualRegister(PtrRC);
- BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::CONST_I32), OffsetReg)
+ BuildMI(MBB, InsertPt, DL, TII->get(getOpcConst(MF)), OffsetReg)
.addImm(StackSize);
- BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::SUB_I32),
- WebAssembly::SP32)
+ BuildMI(MBB, InsertPt, DL, TII->get(getOpcSub(MF)), getSPReg(MF))
.addReg(SPReg)
.addReg(OffsetReg);
}
if (HasBP) {
Register BitmaskReg = MRI.createVirtualRegister(PtrRC);
Align Alignment = MFI.getMaxAlign();
- BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::CONST_I32), BitmaskReg)
- .addImm((int)~(Alignment.value() - 1));
- BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::AND_I32),
- WebAssembly::SP32)
- .addReg(WebAssembly::SP32)
+ BuildMI(MBB, InsertPt, DL, TII->get(getOpcConst(MF)), BitmaskReg)
+ .addImm((int64_t) ~(Alignment.value() - 1));
+ BuildMI(MBB, InsertPt, DL, TII->get(getOpcAnd(MF)), getSPReg(MF))
+ .addReg(getSPReg(MF))
.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);
+ BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::COPY), getFPReg(MF))
+ .addReg(getSPReg(MF));
}
if (StackSize && needsSPWriteback(MF)) {
- writeSPToGlobal(WebAssembly::SP32, MF, MBB, InsertPt, DL);
+ writeSPToGlobal(getSPReg(MF), MF, MBB, InsertPt, DL);
}
}
@@ -226,7 +278,8 @@
uint64_t StackSize = MF.getFrameInfo().getStackSize();
if (!needsSP(MF) || !needsSPWriteback(MF))
return;
- const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
+ auto &ST = MF.getSubtarget<WebAssemblySubtarget>();
+ const auto *TII = ST.getInstrInfo();
auto &MRI = MF.getRegInfo();
auto InsertPt = MBB.getFirstTerminator();
DebugLoc DL;
@@ -237,6 +290,7 @@
// Restore the stack pointer. If we had fixed-size locals, add the offset
// subtracted in the prolog.
unsigned SPReg = 0;
+ unsigned SPFPReg = hasFP(MF) ? getFPReg(MF) : getSPReg(MF);
if (hasBP(MF)) {
auto FI = MF.getInfo<WebAssemblyFunctionInfo>();
SPReg = FI->getBasePointerVreg();
@@ -244,16 +298,17 @@
const TargetRegisterClass *PtrRC =
MRI.getTargetRegisterInfo()->getPointerRegClass(MF);
Register OffsetReg = MRI.createVirtualRegister(PtrRC);
- BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::CONST_I32), OffsetReg)
+ BuildMI(MBB, InsertPt, DL, TII->get(getOpcConst(MF)), OffsetReg)
.addImm(StackSize);
- // In the epilog we don't need to write the result back to the SP32 physreg
- // because it won't be used again. We can use a stackified register instead.
+ // In the epilog we don't need to write the result back to the SP32/64
+ // physreg because it won't be used again. We can use a stackified register
+ // instead.
SPReg = MRI.createVirtualRegister(PtrRC);
- BuildMI(MBB, InsertPt, DL, TII->get(WebAssembly::ADD_I32), SPReg)
- .addReg(hasFP(MF) ? WebAssembly::FP32 : WebAssembly::SP32)
+ BuildMI(MBB, InsertPt, DL, TII->get(getOpcAdd(MF)), SPReg)
+ .addReg(SPFPReg)
.addReg(OffsetReg);
} else {
- SPReg = hasFP(MF) ? WebAssembly::FP32 : WebAssembly::SP32;
+ SPReg = SPFPReg;
}
writeSPToGlobal(SPReg, MF, MBB, InsertPt, DL);
Index: llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
===================================================================
--- llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -434,9 +434,12 @@
// GetExternalSymbolSymbol does, since if there's no code that
// refers to this symbol, we have to set it here.
SPSym->setType(wasm::WASM_SYMBOL_TYPE_GLOBAL);
- // FIXME: need to check subtarget to see if its wasm64, but we
- // can't cast to WebAssemblySubtarget here.
- SPSym->setGlobalType(wasm::WasmGlobalType{wasm::WASM_TYPE_I32, true});
+ SPSym->setGlobalType(wasm::WasmGlobalType{
+ uint8_t(Asm->getSubtargetInfo().getTargetTriple().getArch() ==
+ Triple::wasm64
+ ? wasm::WASM_TYPE_I64
+ : wasm::WASM_TYPE_I32),
+ true});
DIELoc *Loc = new (DIEValueAllocator) DIELoc;
addUInt(*Loc, dwarf::DW_FORM_data1, dwarf::DW_OP_WASM_location);
addSInt(*Loc, dwarf::DW_FORM_sdata, FrameBase.Location.WasmLoc.Kind);
Index: llvm/include/llvm/BinaryFormat/Wasm.h
===================================================================
--- llvm/include/llvm/BinaryFormat/Wasm.h
+++ llvm/include/llvm/BinaryFormat/Wasm.h
@@ -253,11 +253,13 @@
WASM_OPCODE_GLOBAL_GET = 0x23,
WASM_OPCODE_GLOBAL_SET = 0x24,
WASM_OPCODE_I32_STORE = 0x36,
+ WASM_OPCODE_I64_STORE = 0x37,
WASM_OPCODE_I32_CONST = 0x41,
WASM_OPCODE_I64_CONST = 0x42,
WASM_OPCODE_F32_CONST = 0x43,
WASM_OPCODE_F64_CONST = 0x44,
WASM_OPCODE_I32_ADD = 0x6a,
+ WASM_OPCODE_I64_ADD = 0x7c,
};
// Opcodes used in synthetic functions.
Index: lld/wasm/Options.td
===================================================================
--- lld/wasm/Options.td
+++ lld/wasm/Options.td
@@ -62,6 +62,8 @@
def L: JoinedOrSeparate<["-"], "L">, MetaVarName<"<dir>">,
HelpText<"Add a directory to the library search path">;
+def m: JoinedOrSeparate<["-"], "m">, HelpText<"Set target emulation">;
+
def mllvm: S<"mllvm">, HelpText<"Options to pass to LLVM">;
def no_color_diagnostics: F<"no-color-diagnostics">,
@@ -179,7 +181,6 @@
def: J<"entry=">, Alias<entry>;
def: Flag<["-"], "E">, Alias<export_dynamic>, HelpText<"Alias for --export-dynamic">;
def: Flag<["-"], "i">, Alias<initial_memory>;
-def: Flag<["-"], "m">, Alias<max_memory>;
def: Flag<["-"], "r">, Alias<relocatable>;
def: Flag<["-"], "s">, Alias<strip_all>, HelpText<"Alias for --strip-all">;
def: Flag<["-"], "S">, Alias<strip_debug>, HelpText<"Alias for --strip-debug">;
Index: lld/wasm/InputChunks.cpp
===================================================================
--- lld/wasm/InputChunks.cpp
+++ lld/wasm/InputChunks.cpp
@@ -32,6 +32,18 @@
llvm_unreachable("unknown reloc type");
}
+bool relocIs64(uint8_t relocType) {
+ switch (relocType) {
+ case R_WASM_MEMORY_ADDR_LEB64:
+ case R_WASM_MEMORY_ADDR_SLEB64:
+ case R_WASM_MEMORY_ADDR_REL_SLEB64:
+ case R_WASM_MEMORY_ADDR_I64:
+ return true;
+ default:
+ return false;
+ }
+}
+
std::string toString(const wasm::InputChunk *c) {
return (toString(c->file) + ":(" + c->getName() + ")").str();
}
@@ -323,12 +335,17 @@
LLVM_DEBUG(dbgs() << "generating runtime relocations: " << getName()
<< " count=" << relocations.size() << "\n");
+ auto WASM_OPCODE_PTR_CONST =
+ config->is64 ? WASM_OPCODE_I64_CONST : WASM_OPCODE_I32_CONST;
+ auto WASM_OPCODE_PTR_ADD =
+ config->is64 ? WASM_OPCODE_I64_ADD : WASM_OPCODE_I32_ADD;
+
// TODO(sbc): Encode the relocations in the data section and write a loop
// here to apply them.
uint32_t segmentVA = outputSeg->startVA + outputSegmentOffset;
for (const WasmRelocation &rel : relocations) {
- uint32_t offset = rel.Offset - getInputSectionOffset();
- uint32_t outputOffset = segmentVA + offset;
+ uint64_t offset = rel.Offset - getInputSectionOffset();
+ uint64_t outputOffset = segmentVA + offset;
LLVM_DEBUG(dbgs() << "gen reloc: type=" << relocTypeToString(rel.Type)
<< " addend=" << rel.Addend << " index=" << rel.Index
@@ -339,9 +356,17 @@
writeUleb128(os, WasmSym::memoryBase->getGlobalIndex(), "memory_base");
// Add the offset of the relocation
- writeU8(os, WASM_OPCODE_I32_CONST, "I32_CONST");
+ writeU8(os, WASM_OPCODE_PTR_CONST, "CONST");
writeSleb128(os, outputOffset, "offset");
- writeU8(os, WASM_OPCODE_I32_ADD, "ADD");
+ writeU8(os, WASM_OPCODE_PTR_ADD, "ADD");
+
+ auto is64 = relocIs64(rel.Type);
+ auto WASM_OPCODE_RELOC_CONST =
+ is64 ? WASM_OPCODE_I64_CONST : WASM_OPCODE_I32_CONST;
+ auto WASM_OPCODE_RELOC_ADD =
+ is64 ? WASM_OPCODE_I64_ADD : WASM_OPCODE_I32_ADD;
+ auto WASM_OPCODE_RELOC_STORE =
+ is64 ? WASM_OPCODE_I64_STORE : WASM_OPCODE_I32_STORE;
Symbol *sym = file->getSymbol(rel);
// Now figure out what we want to store
@@ -349,9 +374,9 @@
writeU8(os, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET");
writeUleb128(os, sym->getGOTIndex(), "global index");
if (rel.Addend) {
- writeU8(os, WASM_OPCODE_I32_CONST, "CONST");
+ writeU8(os, WASM_OPCODE_RELOC_CONST, "CONST");
writeSleb128(os, rel.Addend, "addend");
- writeU8(os, WASM_OPCODE_I32_ADD, "ADD");
+ writeU8(os, WASM_OPCODE_RELOC_ADD, "ADD");
}
} else {
const GlobalSymbol* baseSymbol = WasmSym::memoryBase;
@@ -359,13 +384,13 @@
baseSymbol = WasmSym::tableBase;
writeU8(os, WASM_OPCODE_GLOBAL_GET, "GLOBAL_GET");
writeUleb128(os, baseSymbol->getGlobalIndex(), "base");
- writeU8(os, WASM_OPCODE_I32_CONST, "CONST");
+ writeU8(os, WASM_OPCODE_RELOC_CONST, "CONST");
writeSleb128(os, file->calcNewValue(rel), "offset");
- writeU8(os, WASM_OPCODE_I32_ADD, "ADD");
+ writeU8(os, WASM_OPCODE_RELOC_ADD, "ADD");
}
// Store that value at the virtual address
- writeU8(os, WASM_OPCODE_I32_STORE, "I32_STORE");
+ writeU8(os, WASM_OPCODE_RELOC_STORE, "I32_STORE");
writeUleb128(os, 2, "align");
writeUleb128(os, 0, "offset");
}
Index: lld/wasm/Driver.cpp
===================================================================
--- lld/wasm/Driver.cpp
+++ lld/wasm/Driver.cpp
@@ -378,6 +378,18 @@
config->exportDynamic =
args.hasFlag(OPT_export_dynamic, OPT_no_export_dynamic, config->shared);
+ // Parse wasm32/64.
+ config->is64 = false;
+ if (auto *arg = args.getLastArg(OPT_m)) {
+ StringRef s = arg->getValue();
+ if (s == "wasm32")
+ config->is64 = false;
+ else if (s == "wasm64")
+ config->is64 = true;
+ else
+ error("'" + s + "' not a valid target");
+ }
+
// --threads= takes a positive integer and provides the default value for
// --thinlto-jobs=.
if (auto *arg = args.getLastArg(OPT_threads)) {
@@ -498,9 +510,15 @@
static GlobalSymbol *createGlobalVariable(StringRef name, bool isMutable,
int value) {
llvm::wasm::WasmGlobal wasmGlobal;
- wasmGlobal.Type = {WASM_TYPE_I32, isMutable};
- wasmGlobal.InitExpr.Value.Int32 = value;
- wasmGlobal.InitExpr.Opcode = WASM_OPCODE_I32_CONST;
+ if (config->is64) {
+ wasmGlobal.Type = {WASM_TYPE_I64, isMutable};
+ wasmGlobal.InitExpr.Value.Int64 = value;
+ wasmGlobal.InitExpr.Opcode = WASM_OPCODE_I64_CONST;
+ } else {
+ wasmGlobal.Type = {WASM_TYPE_I32, isMutable};
+ wasmGlobal.InitExpr.Value.Int32 = value;
+ wasmGlobal.InitExpr.Opcode = WASM_OPCODE_I32_CONST;
+ }
wasmGlobal.SymbolName = name;
return symtab->addSyntheticGlobal(name, WASM_SYMBOL_VISIBILITY_HIDDEN,
make<InputGlobal>(wasmGlobal, nullptr));
@@ -513,9 +531,13 @@
static WasmSignature nullSignature = {{}, {}};
static WasmSignature i32ArgSignature = {{}, {ValType::I32}};
+ static WasmSignature i64ArgSignature = {{}, {ValType::I64}};
static llvm::wasm::WasmGlobalType globalTypeI32 = {WASM_TYPE_I32, false};
+ static llvm::wasm::WasmGlobalType globalTypeI64 = {WASM_TYPE_I64, false};
static llvm::wasm::WasmGlobalType mutableGlobalTypeI32 = {WASM_TYPE_I32,
true};
+ static llvm::wasm::WasmGlobalType mutableGlobalTypeI64 = {WASM_TYPE_I64,
+ true};
WasmSym::callCtors = symtab->addSyntheticFunction(
"__wasm_call_ctors", WASM_SYMBOL_VISIBILITY_HIDDEN,
make<SyntheticFunction>(nullSignature, "__wasm_call_ctors"));
@@ -530,15 +552,16 @@
if (config->isPic) {
- WasmSym::stackPointer =
- createUndefinedGlobal("__stack_pointer", &mutableGlobalTypeI32);
+ WasmSym::stackPointer = createUndefinedGlobal(
+ "__stack_pointer",
+ config->is64 ? &mutableGlobalTypeI64 : &mutableGlobalTypeI32);
// For PIC code, we import two global variables (__memory_base and
// __table_base) from the environment and use these as the offset at
// which to load our static data and function table.
// See:
// https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md
- WasmSym::memoryBase =
- createUndefinedGlobal("__memory_base", &globalTypeI32);
+ WasmSym::memoryBase = createUndefinedGlobal(
+ "__memory_base", config->is64 ? &globalTypeI64 : &globalTypeI32);
WasmSym::tableBase = createUndefinedGlobal("__table_base", &globalTypeI32);
WasmSym::memoryBase->markLive();
WasmSym::tableBase->markLive();
@@ -563,7 +586,9 @@
WasmSym::tlsAlign = createGlobalVariable("__tls_align", false, 1);
WasmSym::initTLS = symtab->addSyntheticFunction(
"__wasm_init_tls", WASM_SYMBOL_VISIBILITY_HIDDEN,
- make<SyntheticFunction>(i32ArgSignature, "__wasm_init_tls"));
+ make<SyntheticFunction>(config->is64 ? i64ArgSignature
+ : i32ArgSignature,
+ "__wasm_init_tls"));
}
}
Index: lld/wasm/Config.h
===================================================================
--- lld/wasm/Config.h
+++ lld/wasm/Config.h
@@ -36,6 +36,7 @@
bool importMemory;
bool sharedMemory;
bool importTable;
+ bool is64;
bool mergeDataSegments;
bool pie;
bool printGcSections;
Index: clang/lib/Driver/ToolChains/WebAssembly.cpp
===================================================================
--- clang/lib/Driver/ToolChains/WebAssembly.cpp
+++ clang/lib/Driver/ToolChains/WebAssembly.cpp
@@ -62,6 +62,11 @@
const char *Linker = Args.MakeArgString(getLinkerPath(Args));
ArgStringList CmdArgs;
+ if (getToolChain().getTriple().isArch64Bit())
+ CmdArgs.push_back("-m wasm64");
+ else
+ CmdArgs.push_back("-m wasm32");
+
if (Args.hasArg(options::OPT_s))
CmdArgs.push_back("--strip-all");
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits