summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/WebAssembly
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/WebAssembly')
-rw-r--r--llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h9
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp11
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp3
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyInstrMemory.td58
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyPeephole.cpp19
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp7
-rw-r--r--llvm/lib/Target/WebAssembly/WebAssemblySetP2AlignOperands.cpp45
7 files changed, 64 insertions, 88 deletions
diff --git a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
index 0fc65e5a836..c7d6efb794f 100644
--- a/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
+++ b/llvm/lib/Target/WebAssembly/MCTargetDesc/WebAssemblyMCTargetDesc.h
@@ -134,9 +134,12 @@ inline unsigned GetDefaultP2Align(unsigned Opcode) {
}
/// The operand number of the load or store address in load/store instructions.
-static const unsigned MemOpAddressOperandNo = 2;
-/// The operand number of the stored value in a store instruction.
-static const unsigned StoreValueOperandNo = 4;
+static const unsigned LoadAddressOperandNo = 2;
+static const unsigned StoreAddressOperandNo = 1;
+
+/// The operand number of the load or store p2align in load/store instructions.
+static const unsigned LoadP2AlignOperandNo = 3;
+static const unsigned StoreP2AlignOperandNo = 2;
} // end namespace WebAssembly
} // end namespace llvm
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
index 2f409622795..64d4dae9647 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyFastISel.cpp
@@ -1092,34 +1092,27 @@ bool WebAssemblyFastISel::selectStore(const Instruction *I) {
return false;
unsigned Opc;
- const TargetRegisterClass *RC;
bool VTIsi1 = false;
switch (getSimpleType(Store->getValueOperand()->getType())) {
case MVT::i1:
VTIsi1 = true;
case MVT::i8:
Opc = WebAssembly::STORE8_I32;
- RC = &WebAssembly::I32RegClass;
break;
case MVT::i16:
Opc = WebAssembly::STORE16_I32;
- RC = &WebAssembly::I32RegClass;
break;
case MVT::i32:
Opc = WebAssembly::STORE_I32;
- RC = &WebAssembly::I32RegClass;
break;
case MVT::i64:
Opc = WebAssembly::STORE_I64;
- RC = &WebAssembly::I64RegClass;
break;
case MVT::f32:
Opc = WebAssembly::STORE_F32;
- RC = &WebAssembly::F32RegClass;
break;
case MVT::f64:
Opc = WebAssembly::STORE_F64;
- RC = &WebAssembly::F64RegClass;
break;
default: return false;
}
@@ -1132,9 +1125,7 @@ bool WebAssemblyFastISel::selectStore(const Instruction *I) {
if (VTIsi1)
ValueReg = maskI1Value(ValueReg, Store->getValueOperand());
- unsigned ResultReg = createResultReg(RC);
- auto MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc),
- ResultReg);
+ auto MIB = BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(Opc));
addLoadStoreOperands(Addr, MIB, createMachineMemOperandFor(Store));
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp
index 99205402653..6523ea55966 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyFrameLowering.cpp
@@ -88,7 +88,6 @@ static void writeSPToMemory(unsigned SrcReg, MachineFunction &MF,
const TargetRegisterClass *PtrRC =
MRI.getTargetRegisterInfo()->getPointerRegClass(MF);
unsigned Zero = MRI.createVirtualRegister(PtrRC);
- unsigned Drop = MRI.createVirtualRegister(PtrRC);
const auto *TII = MF.getSubtarget<WebAssemblySubtarget>().getInstrInfo();
BuildMI(MBB, InsertAddr, DL, TII->get(WebAssembly::CONST_I32), Zero)
@@ -96,7 +95,7 @@ static void writeSPToMemory(unsigned SrcReg, MachineFunction &MF,
MachineMemOperand *MMO = MF.getMachineMemOperand(
MachinePointerInfo(MF.getPSVManager().getExternalSymbolCallEntry(ES)),
MachineMemOperand::MOStore, 4, 4);
- BuildMI(MBB, InsertStore, DL, TII->get(WebAssembly::STORE_I32), Drop)
+ BuildMI(MBB, InsertStore, DL, TII->get(WebAssembly::STORE_I32))
.addExternalSymbol(SPSymbol)
.addReg(Zero)
.addImm(2) // p2align
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyInstrMemory.td b/llvm/lib/Target/WebAssembly/WebAssemblyInstrMemory.td
index 7535ece1c2d..2a96aa04ca3 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyInstrMemory.td
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyInstrMemory.td
@@ -446,23 +446,19 @@ def : Pat<(i64 (extloadi32 (WebAssemblywrapper texternalsym:$off))),
let Defs = [ARGUMENTS] in {
// Basic store.
-// Note that we split the patterns out of the instruction definitions because
-// WebAssembly's stores return their operand value, and tablegen doesn't like
-// instruction definition patterns that don't reference all of the output
-// operands.
// Note: WebAssembly inverts SelectionDAG's usual operand order.
-def STORE_I32 : I<(outs I32:$dst), (ins i32imm:$off, I32:$addr,
- P2Align:$p2align, I32:$val), [],
- "i32.store\t$dst, ${off}(${addr})${p2align}, $val", 0x33>;
-def STORE_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr,
- P2Align:$p2align, I64:$val), [],
- "i64.store\t$dst, ${off}(${addr})${p2align}, $val", 0x34>;
-def STORE_F32 : I<(outs F32:$dst), (ins i32imm:$off, I32:$addr,
- P2Align:$p2align, F32:$val), [],
- "f32.store\t$dst, ${off}(${addr})${p2align}, $val", 0x35>;
-def STORE_F64 : I<(outs F64:$dst), (ins i32imm:$off, I32:$addr,
- P2Align:$p2align, F64:$val), [],
- "f64.store\t$dst, ${off}(${addr})${p2align}, $val", 0x36>;
+def STORE_I32 : I<(outs), (ins i32imm:$off, I32:$addr,
+ P2Align:$p2align, I32:$val), [],
+ "i32.store\t${off}(${addr})${p2align}, $val", 0x33>;
+def STORE_I64 : I<(outs), (ins i32imm:$off, I32:$addr,
+ P2Align:$p2align, I64:$val), [],
+ "i64.store\t${off}(${addr})${p2align}, $val", 0x34>;
+def STORE_F32 : I<(outs), (ins i32imm:$off, I32:$addr,
+ P2Align:$p2align, F32:$val), [],
+ "f32.store\t${off}(${addr})${p2align}, $val", 0x35>;
+def STORE_F64 : I<(outs), (ins i32imm:$off, I32:$addr,
+ P2Align:$p2align, F64:$val), [],
+ "f64.store\t${off}(${addr})${p2align}, $val", 0x36>;
} // Defs = [ARGUMENTS]
@@ -543,21 +539,21 @@ def : Pat<(store F64:$val, (WebAssemblywrapper texternalsym:$off)),
let Defs = [ARGUMENTS] in {
// Truncating store.
-def STORE8_I32 : I<(outs I32:$dst), (ins i32imm:$off, I32:$addr,
- P2Align:$p2align, I32:$val), [],
- "i32.store8\t$dst, ${off}(${addr})${p2align}, $val", 0x2e>;
-def STORE16_I32 : I<(outs I32:$dst), (ins i32imm:$off, I32:$addr,
- P2Align:$p2align, I32:$val), [],
- "i32.store16\t$dst, ${off}(${addr})${p2align}, $val", 0x2f>;
-def STORE8_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr,
- P2Align:$p2align, I64:$val), [],
- "i64.store8\t$dst, ${off}(${addr})${p2align}, $val", 0x30>;
-def STORE16_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr,
- P2Align:$p2align, I64:$val), [],
- "i64.store16\t$dst, ${off}(${addr})${p2align}, $val", 0x31>;
-def STORE32_I64 : I<(outs I64:$dst), (ins i32imm:$off, I32:$addr,
- P2Align:$p2align, I64:$val), [],
- "i64.store32\t$dst, ${off}(${addr})${p2align}, $val", 0x32>;
+def STORE8_I32 : I<(outs), (ins i32imm:$off, I32:$addr,
+ P2Align:$p2align, I32:$val), [],
+ "i32.store8\t${off}(${addr})${p2align}, $val", 0x2e>;
+def STORE16_I32 : I<(outs), (ins i32imm:$off, I32:$addr,
+ P2Align:$p2align, I32:$val), [],
+ "i32.store16\t${off}(${addr})${p2align}, $val", 0x2f>;
+def STORE8_I64 : I<(outs), (ins i32imm:$off, I32:$addr,
+ P2Align:$p2align, I64:$val), [],
+ "i64.store8\t${off}(${addr})${p2align}, $val", 0x30>;
+def STORE16_I64 : I<(outs), (ins i32imm:$off, I32:$addr,
+ P2Align:$p2align, I64:$val), [],
+ "i64.store16\t${off}(${addr})${p2align}, $val", 0x31>;
+def STORE32_I64 : I<(outs), (ins i32imm:$off, I32:$addr,
+ P2Align:$p2align, I64:$val), [],
+ "i64.store32\t${off}(${addr})${p2align}, $val", 0x32>;
} // Defs = [ARGUMENTS]
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyPeephole.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyPeephole.cpp
index 0120431c639..a9e970c399d 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyPeephole.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyPeephole.cpp
@@ -119,25 +119,6 @@ bool WebAssemblyPeephole::runOnMachineFunction(MachineFunction &MF) {
switch (MI.getOpcode()) {
default:
break;
- case WebAssembly::STORE8_I32:
- case WebAssembly::STORE16_I32:
- case WebAssembly::STORE8_I64:
- case WebAssembly::STORE16_I64:
- case WebAssembly::STORE32_I64:
- case WebAssembly::STORE_F32:
- case WebAssembly::STORE_F64:
- case WebAssembly::STORE_I32:
- case WebAssembly::STORE_I64: {
- // Store instructions return their value operand. If we ended up using
- // the same register for both, replace it with a dead def so that it
- // can use $drop instead.
- MachineOperand &MO = MI.getOperand(0);
- unsigned OldReg = MO.getReg();
- unsigned NewReg =
- MI.getOperand(WebAssembly::StoreValueOperandNo).getReg();
- Changed |= MaybeRewriteToDrop(OldReg, NewReg, MO, MFI, MRI);
- break;
- }
case WebAssembly::CALL_I32:
case WebAssembly::CALL_I64: {
MachineOperand &Op1 = MI.getOperand(1);
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp b/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp
index bb8fe9ae996..9367464c806 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblyRegisterInfo.cpp
@@ -71,9 +71,10 @@ void WebAssemblyRegisterInfo::eliminateFrameIndex(
// If this is the address operand of a load or store, make it relative to SP
// and fold the frame offset directly in.
- if (MI.mayLoadOrStore() && FIOperandNum == WebAssembly::MemOpAddressOperandNo) {
- assert(FrameOffset >= 0 && MI.getOperand(1).getImm() >= 0);
- int64_t Offset = MI.getOperand(1).getImm() + FrameOffset;
+ if ((MI.mayLoad() && FIOperandNum == WebAssembly::LoadAddressOperandNo) ||
+ (MI.mayStore() && FIOperandNum == WebAssembly::StoreAddressOperandNo)) {
+ assert(FrameOffset >= 0 && MI.getOperand(FIOperandNum - 1).getImm() >= 0);
+ int64_t Offset = MI.getOperand(FIOperandNum - 1).getImm() + FrameOffset;
if (static_cast<uint64_t>(Offset) <= std::numeric_limits<uint32_t>::max()) {
MI.getOperand(FIOperandNum - 1).setImm(Offset);
diff --git a/llvm/lib/Target/WebAssembly/WebAssemblySetP2AlignOperands.cpp b/llvm/lib/Target/WebAssembly/WebAssemblySetP2AlignOperands.cpp
index 8e0356f12f5..2441ead7cb2 100644
--- a/llvm/lib/Target/WebAssembly/WebAssemblySetP2AlignOperands.cpp
+++ b/llvm/lib/Target/WebAssembly/WebAssemblySetP2AlignOperands.cpp
@@ -50,6 +50,27 @@ FunctionPass *llvm::createWebAssemblySetP2AlignOperands() {
return new WebAssemblySetP2AlignOperands();
}
+static void RewriteP2Align(MachineInstr &MI, unsigned OperandNo) {
+ assert(MI.getOperand(OperandNo).getImm() == 0 &&
+ "ISel should set p2align operands to 0");
+ assert(MI.hasOneMemOperand() &&
+ "Load and store instructions have exactly one mem operand");
+ assert((*MI.memoperands_begin())->getSize() ==
+ (UINT64_C(1)
+ << WebAssembly::GetDefaultP2Align(MI.getOpcode())) &&
+ "Default p2align value should be natural");
+ assert(MI.getDesc().OpInfo[OperandNo].OperandType ==
+ WebAssembly::OPERAND_P2ALIGN &&
+ "Load and store instructions should have a p2align operand");
+ uint64_t P2Align = Log2_64((*MI.memoperands_begin())->getAlignment());
+
+ // WebAssembly does not currently support supernatural alignment.
+ P2Align = std::min(
+ P2Align, uint64_t(WebAssembly::GetDefaultP2Align(MI.getOpcode())));
+
+ MI.getOperand(OperandNo).setImm(P2Align);
+}
+
bool WebAssemblySetP2AlignOperands::runOnMachineFunction(MachineFunction &MF) {
DEBUG({
dbgs() << "********** Set p2align Operands **********\n"
@@ -75,6 +96,8 @@ bool WebAssemblySetP2AlignOperands::runOnMachineFunction(MachineFunction &MF) {
case WebAssembly::LOAD16_U_I64:
case WebAssembly::LOAD32_S_I64:
case WebAssembly::LOAD32_U_I64:
+ RewriteP2Align(MI, WebAssembly::LoadP2AlignOperandNo);
+ break;
case WebAssembly::STORE_I32:
case WebAssembly::STORE_I64:
case WebAssembly::STORE_F32:
@@ -83,27 +106,9 @@ bool WebAssemblySetP2AlignOperands::runOnMachineFunction(MachineFunction &MF) {
case WebAssembly::STORE16_I32:
case WebAssembly::STORE8_I64:
case WebAssembly::STORE16_I64:
- case WebAssembly::STORE32_I64: {
- assert(MI.getOperand(3).getImm() == 0 &&
- "ISel should set p2align operands to 0");
- assert(MI.hasOneMemOperand() &&
- "Load and store instructions have exactly one mem operand");
- assert((*MI.memoperands_begin())->getSize() ==
- (UINT64_C(1)
- << WebAssembly::GetDefaultP2Align(MI.getOpcode())) &&
- "Default p2align value should be natural");
- assert(MI.getDesc().OpInfo[3].OperandType ==
- WebAssembly::OPERAND_P2ALIGN &&
- "Load and store instructions should have a p2align operand");
- uint64_t P2Align = Log2_64((*MI.memoperands_begin())->getAlignment());
-
- // WebAssembly does not currently support supernatural alignment.
- P2Align = std::min(
- P2Align, uint64_t(WebAssembly::GetDefaultP2Align(MI.getOpcode())));
-
- MI.getOperand(3).setImm(P2Align);
+ case WebAssembly::STORE32_I64:
+ RewriteP2Align(MI, WebAssembly::StoreP2AlignOperandNo);
break;
- }
default:
break;
}
OpenPOWER on IntegriCloud