mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-18 18:42:46 +02:00
Revert "[WebAssembly] Added default stack-only instruction mode for MC."
This reverts commit d3c9af4179eae7793d1487d652e2d4e23844555f. (SVN revision 338164) llvm-svn: 338176
This commit is contained in:
parent
f8062a5b78
commit
e977320a0d
@ -34,10 +34,27 @@ using namespace llvm;
|
|||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
// We store register types as SimpleValueType to retain SIMD layout
|
||||||
|
// information, but must also be able to supply them as the (unnamed)
|
||||||
|
// register enum from WebAssemblyRegisterInfo.td/.inc.
|
||||||
|
static unsigned MVTToWasmReg(MVT::SimpleValueType Type) {
|
||||||
|
switch(Type) {
|
||||||
|
case MVT::i32: return WebAssembly::I32_0;
|
||||||
|
case MVT::i64: return WebAssembly::I64_0;
|
||||||
|
case MVT::f32: return WebAssembly::F32_0;
|
||||||
|
case MVT::f64: return WebAssembly::F64_0;
|
||||||
|
case MVT::v16i8: return WebAssembly::V128_0;
|
||||||
|
case MVT::v8i16: return WebAssembly::V128_0;
|
||||||
|
case MVT::v4i32: return WebAssembly::V128_0;
|
||||||
|
case MVT::v4f32: return WebAssembly::V128_0;
|
||||||
|
default: return MVT::INVALID_SIMPLE_VALUE_TYPE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// WebAssemblyOperand - Instances of this class represent the operands in a
|
/// WebAssemblyOperand - Instances of this class represent the operands in a
|
||||||
/// parsed WASM machine instruction.
|
/// parsed WASM machine instruction.
|
||||||
struct WebAssemblyOperand : public MCParsedAsmOperand {
|
struct WebAssemblyOperand : public MCParsedAsmOperand {
|
||||||
enum KindTy { Token, Integer, Float, Symbol } Kind;
|
enum KindTy { Token, Local, Stack, Integer, Float, Symbol } Kind;
|
||||||
|
|
||||||
SMLoc StartLoc, EndLoc;
|
SMLoc StartLoc, EndLoc;
|
||||||
|
|
||||||
@ -45,6 +62,19 @@ struct WebAssemblyOperand : public MCParsedAsmOperand {
|
|||||||
StringRef Tok;
|
StringRef Tok;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct RegOp {
|
||||||
|
// This is a (virtual) local or stack register represented as 0..
|
||||||
|
unsigned RegNo;
|
||||||
|
// In most targets, the register number also encodes the type, but for
|
||||||
|
// wasm we have to track that seperately since we have an unbounded
|
||||||
|
// number of registers.
|
||||||
|
// This has the unfortunate side effect that we supply a different value
|
||||||
|
// to the table-gen matcher at different times in the process (when it
|
||||||
|
// calls getReg() or addRegOperands().
|
||||||
|
// TODO: While this works, it feels brittle. and would be nice to clean up.
|
||||||
|
MVT::SimpleValueType Type;
|
||||||
|
};
|
||||||
|
|
||||||
struct IntOp {
|
struct IntOp {
|
||||||
int64_t Val;
|
int64_t Val;
|
||||||
};
|
};
|
||||||
@ -59,6 +89,7 @@ struct WebAssemblyOperand : public MCParsedAsmOperand {
|
|||||||
|
|
||||||
union {
|
union {
|
||||||
struct TokOp Tok;
|
struct TokOp Tok;
|
||||||
|
struct RegOp Reg;
|
||||||
struct IntOp Int;
|
struct IntOp Int;
|
||||||
struct FltOp Flt;
|
struct FltOp Flt;
|
||||||
struct SymOp Sym;
|
struct SymOp Sym;
|
||||||
@ -66,6 +97,8 @@ struct WebAssemblyOperand : public MCParsedAsmOperand {
|
|||||||
|
|
||||||
WebAssemblyOperand(KindTy K, SMLoc Start, SMLoc End, TokOp T)
|
WebAssemblyOperand(KindTy K, SMLoc Start, SMLoc End, TokOp T)
|
||||||
: Kind(K), StartLoc(Start), EndLoc(End), Tok(T) {}
|
: Kind(K), StartLoc(Start), EndLoc(End), Tok(T) {}
|
||||||
|
WebAssemblyOperand(KindTy K, SMLoc Start, SMLoc End, RegOp R)
|
||||||
|
: Kind(K), StartLoc(Start), EndLoc(End), Reg(R) {}
|
||||||
WebAssemblyOperand(KindTy K, SMLoc Start, SMLoc End, IntOp I)
|
WebAssemblyOperand(KindTy K, SMLoc Start, SMLoc End, IntOp I)
|
||||||
: Kind(K), StartLoc(Start), EndLoc(End), Int(I) {}
|
: Kind(K), StartLoc(Start), EndLoc(End), Int(I) {}
|
||||||
WebAssemblyOperand(KindTy K, SMLoc Start, SMLoc End, FltOp F)
|
WebAssemblyOperand(KindTy K, SMLoc Start, SMLoc End, FltOp F)
|
||||||
@ -77,12 +110,14 @@ struct WebAssemblyOperand : public MCParsedAsmOperand {
|
|||||||
bool isImm() const override { return Kind == Integer ||
|
bool isImm() const override { return Kind == Integer ||
|
||||||
Kind == Float ||
|
Kind == Float ||
|
||||||
Kind == Symbol; }
|
Kind == Symbol; }
|
||||||
|
bool isReg() const override { return Kind == Local || Kind == Stack; }
|
||||||
bool isMem() const override { return false; }
|
bool isMem() const override { return false; }
|
||||||
bool isReg() const override { return false; }
|
|
||||||
|
|
||||||
unsigned getReg() const override {
|
unsigned getReg() const override {
|
||||||
llvm_unreachable("Assembly inspects a register operand");
|
assert(isReg());
|
||||||
return 0;
|
// This is called from the tablegen matcher (MatchInstructionImpl)
|
||||||
|
// where it expects to match the type of register, see RegOp above.
|
||||||
|
return MVTToWasmReg(Reg.Type);
|
||||||
}
|
}
|
||||||
|
|
||||||
StringRef getToken() const {
|
StringRef getToken() const {
|
||||||
@ -93,9 +128,19 @@ struct WebAssemblyOperand : public MCParsedAsmOperand {
|
|||||||
SMLoc getStartLoc() const override { return StartLoc; }
|
SMLoc getStartLoc() const override { return StartLoc; }
|
||||||
SMLoc getEndLoc() const override { return EndLoc; }
|
SMLoc getEndLoc() const override { return EndLoc; }
|
||||||
|
|
||||||
void addRegOperands(MCInst &, unsigned) const {
|
void addRegOperands(MCInst &Inst, unsigned N) const {
|
||||||
// Required by the assembly matcher.
|
assert(N == 1 && "Invalid number of operands!");
|
||||||
llvm_unreachable("Assembly matcher creates register operands");
|
assert(isReg() && "Not a register operand!");
|
||||||
|
// This is called from the tablegen matcher (MatchInstructionImpl)
|
||||||
|
// where it expects to output the actual register index, see RegOp above.
|
||||||
|
unsigned R = Reg.RegNo;
|
||||||
|
if (Kind == Stack) {
|
||||||
|
// A stack register is represented as a large negative number.
|
||||||
|
// See WebAssemblyRegNumbering::runOnMachineFunction and
|
||||||
|
// getWARegStackId for why this | is needed.
|
||||||
|
R |= INT32_MIN;
|
||||||
|
}
|
||||||
|
Inst.addOperand(MCOperand::createReg(R));
|
||||||
}
|
}
|
||||||
|
|
||||||
void addImmOperands(MCInst &Inst, unsigned N) const {
|
void addImmOperands(MCInst &Inst, unsigned N) const {
|
||||||
@ -115,6 +160,12 @@ struct WebAssemblyOperand : public MCParsedAsmOperand {
|
|||||||
case Token:
|
case Token:
|
||||||
OS << "Tok:" << Tok.Tok;
|
OS << "Tok:" << Tok.Tok;
|
||||||
break;
|
break;
|
||||||
|
case Local:
|
||||||
|
OS << "Loc:" << Reg.RegNo << ":" << static_cast<int>(Reg.Type);
|
||||||
|
break;
|
||||||
|
case Stack:
|
||||||
|
OS << "Stk:" << Reg.RegNo << ":" << static_cast<int>(Reg.Type);
|
||||||
|
break;
|
||||||
case Integer:
|
case Integer:
|
||||||
OS << "Int:" << Int.Val;
|
OS << "Int:" << Int.Val;
|
||||||
break;
|
break;
|
||||||
@ -131,6 +182,11 @@ struct WebAssemblyOperand : public MCParsedAsmOperand {
|
|||||||
class WebAssemblyAsmParser final : public MCTargetAsmParser {
|
class WebAssemblyAsmParser final : public MCTargetAsmParser {
|
||||||
MCAsmParser &Parser;
|
MCAsmParser &Parser;
|
||||||
MCAsmLexer &Lexer;
|
MCAsmLexer &Lexer;
|
||||||
|
// These are for the current function being parsed:
|
||||||
|
// These are vectors since register assignments are so far non-sparse.
|
||||||
|
// Replace by map if necessary.
|
||||||
|
std::vector<MVT::SimpleValueType> LocalTypes;
|
||||||
|
std::vector<MVT::SimpleValueType> StackTypes;
|
||||||
MCSymbol *LastLabel;
|
MCSymbol *LastLabel;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -180,6 +236,68 @@ public:
|
|||||||
.Default(MVT::INVALID_SIMPLE_VALUE_TYPE);
|
.Default(MVT::INVALID_SIMPLE_VALUE_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MVT::SimpleValueType &GetType(
|
||||||
|
std::vector<MVT::SimpleValueType> &Types, size_t i) {
|
||||||
|
Types.resize(std::max(i + 1, Types.size()), MVT::INVALID_SIMPLE_VALUE_TYPE);
|
||||||
|
return Types[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ParseReg(OperandVector &Operands, StringRef TypePrefix) {
|
||||||
|
if (Lexer.is(AsmToken::Integer)) {
|
||||||
|
auto &Local = Lexer.getTok();
|
||||||
|
// This is a reference to a local, turn it into a virtual register.
|
||||||
|
auto LocalNo = static_cast<unsigned>(Local.getIntVal());
|
||||||
|
Operands.push_back(make_unique<WebAssemblyOperand>(
|
||||||
|
WebAssemblyOperand::Local, Local.getLoc(),
|
||||||
|
Local.getEndLoc(),
|
||||||
|
WebAssemblyOperand::RegOp{LocalNo,
|
||||||
|
GetType(LocalTypes, LocalNo)}));
|
||||||
|
Parser.Lex();
|
||||||
|
} else if (Lexer.is(AsmToken::Identifier)) {
|
||||||
|
auto &StackRegTok = Lexer.getTok();
|
||||||
|
// These are push/pop/drop pseudo stack registers, which we turn
|
||||||
|
// into virtual registers also. The stackify pass will later turn them
|
||||||
|
// back into implicit stack references if possible.
|
||||||
|
auto StackReg = StackRegTok.getString();
|
||||||
|
auto StackOp = StackReg.take_while([](char c) { return isalpha(c); });
|
||||||
|
auto Reg = StackReg.drop_front(StackOp.size());
|
||||||
|
unsigned long long ParsedRegNo = 0;
|
||||||
|
if (!Reg.empty() && getAsUnsignedInteger(Reg, 10, ParsedRegNo))
|
||||||
|
return Error("Cannot parse stack register index: ", StackRegTok);
|
||||||
|
unsigned RegNo = static_cast<unsigned>(ParsedRegNo);
|
||||||
|
if (StackOp == "push") {
|
||||||
|
// This defines a result, record register type.
|
||||||
|
auto RegType = ParseRegType(TypePrefix);
|
||||||
|
GetType(StackTypes, RegNo) = RegType;
|
||||||
|
Operands.push_back(make_unique<WebAssemblyOperand>(
|
||||||
|
WebAssemblyOperand::Stack,
|
||||||
|
StackRegTok.getLoc(),
|
||||||
|
StackRegTok.getEndLoc(),
|
||||||
|
WebAssemblyOperand::RegOp{RegNo, RegType}));
|
||||||
|
} else if (StackOp == "pop") {
|
||||||
|
// This uses a previously defined stack value.
|
||||||
|
auto RegType = GetType(StackTypes, RegNo);
|
||||||
|
Operands.push_back(make_unique<WebAssemblyOperand>(
|
||||||
|
WebAssemblyOperand::Stack,
|
||||||
|
StackRegTok.getLoc(),
|
||||||
|
StackRegTok.getEndLoc(),
|
||||||
|
WebAssemblyOperand::RegOp{RegNo, RegType}));
|
||||||
|
} else if (StackOp == "drop") {
|
||||||
|
// This operand will be dropped, since it is part of an instruction
|
||||||
|
// whose result is void.
|
||||||
|
} else {
|
||||||
|
return Error("Unknown stack register prefix: ", StackRegTok);
|
||||||
|
}
|
||||||
|
Parser.Lex();
|
||||||
|
} else {
|
||||||
|
return Error(
|
||||||
|
"Expected identifier/integer following $, instead got: ",
|
||||||
|
Lexer.getTok());
|
||||||
|
}
|
||||||
|
IsNext(AsmToken::Equal);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void ParseSingleInteger(bool IsNegative, OperandVector &Operands) {
|
void ParseSingleInteger(bool IsNegative, OperandVector &Operands) {
|
||||||
auto &Int = Lexer.getTok();
|
auto &Int = Lexer.getTok();
|
||||||
int64_t Val = Int.getIntVal();
|
int64_t Val = Int.getIntVal();
|
||||||
@ -192,26 +310,36 @@ public:
|
|||||||
|
|
||||||
bool ParseOperandStartingWithInteger(bool IsNegative,
|
bool ParseOperandStartingWithInteger(bool IsNegative,
|
||||||
OperandVector &Operands,
|
OperandVector &Operands,
|
||||||
StringRef InstName) {
|
StringRef InstType) {
|
||||||
ParseSingleInteger(IsNegative, Operands);
|
ParseSingleInteger(IsNegative, Operands);
|
||||||
// FIXME: there is probably a cleaner way to do this.
|
if (Lexer.is(AsmToken::LParen)) {
|
||||||
auto IsLoadStore = InstName.startswith("load") ||
|
// Parse load/store operands of the form: offset($reg)align
|
||||||
InstName.startswith("store") ||
|
auto &LParen = Lexer.getTok();
|
||||||
InstName.startswith("atomic_load") ||
|
Operands.push_back(
|
||||||
InstName.startswith("atomic_store");
|
make_unique<WebAssemblyOperand>(WebAssemblyOperand::Token,
|
||||||
if (IsLoadStore) {
|
LParen.getLoc(),
|
||||||
// Parse load/store operands of the form: offset align
|
LParen.getEndLoc(),
|
||||||
auto &Offset = Lexer.getTok();
|
WebAssemblyOperand::TokOp{
|
||||||
if (Offset.is(AsmToken::Integer)) {
|
LParen.getString()}));
|
||||||
|
Parser.Lex();
|
||||||
|
if (Expect(AsmToken::Dollar, "register")) return true;
|
||||||
|
if (ParseReg(Operands, InstType)) return true;
|
||||||
|
auto &RParen = Lexer.getTok();
|
||||||
|
Operands.push_back(
|
||||||
|
make_unique<WebAssemblyOperand>(WebAssemblyOperand::Token,
|
||||||
|
RParen.getLoc(),
|
||||||
|
RParen.getEndLoc(),
|
||||||
|
WebAssemblyOperand::TokOp{
|
||||||
|
RParen.getString()}));
|
||||||
|
if (Expect(AsmToken::RParen, ")")) return true;
|
||||||
|
if (Lexer.is(AsmToken::Integer)) {
|
||||||
ParseSingleInteger(false, Operands);
|
ParseSingleInteger(false, Operands);
|
||||||
} else {
|
} else {
|
||||||
// Alignment not specified.
|
// Alignment not specified.
|
||||||
// FIXME: correctly derive a default from the instruction.
|
// FIXME: correctly derive a default from the instruction.
|
||||||
// We can't just call WebAssembly::GetDefaultP2Align since we don't have
|
|
||||||
// an opcode until after the assembly matcher.
|
|
||||||
Operands.push_back(make_unique<WebAssemblyOperand>(
|
Operands.push_back(make_unique<WebAssemblyOperand>(
|
||||||
WebAssemblyOperand::Integer, Offset.getLoc(),
|
WebAssemblyOperand::Integer, RParen.getLoc(),
|
||||||
Offset.getEndLoc(), WebAssemblyOperand::IntOp{0}));
|
RParen.getEndLoc(), WebAssemblyOperand::IntOp{0}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -232,6 +360,11 @@ public:
|
|||||||
while (Lexer.isNot(AsmToken::EndOfStatement)) {
|
while (Lexer.isNot(AsmToken::EndOfStatement)) {
|
||||||
auto &Tok = Lexer.getTok();
|
auto &Tok = Lexer.getTok();
|
||||||
switch (Tok.getKind()) {
|
switch (Tok.getKind()) {
|
||||||
|
case AsmToken::Dollar: {
|
||||||
|
Parser.Lex();
|
||||||
|
if (ParseReg(Operands, NamePair.first)) return true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case AsmToken::Identifier: {
|
case AsmToken::Identifier: {
|
||||||
auto &Id = Lexer.getTok();
|
auto &Id = Lexer.getTok();
|
||||||
const MCExpr *Val;
|
const MCExpr *Val;
|
||||||
@ -247,11 +380,11 @@ public:
|
|||||||
Parser.Lex();
|
Parser.Lex();
|
||||||
if (Lexer.isNot(AsmToken::Integer))
|
if (Lexer.isNot(AsmToken::Integer))
|
||||||
return Error("Expected integer instead got: ", Lexer.getTok());
|
return Error("Expected integer instead got: ", Lexer.getTok());
|
||||||
if (ParseOperandStartingWithInteger(true, Operands, NamePair.second))
|
if (ParseOperandStartingWithInteger(true, Operands, NamePair.first))
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
case AsmToken::Integer:
|
case AsmToken::Integer:
|
||||||
if (ParseOperandStartingWithInteger(false, Operands, NamePair.second))
|
if (ParseOperandStartingWithInteger(false, Operands, NamePair.first))
|
||||||
return true;
|
return true;
|
||||||
break;
|
break;
|
||||||
case AsmToken::Real: {
|
case AsmToken::Real: {
|
||||||
@ -272,6 +405,35 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Parser.Lex();
|
Parser.Lex();
|
||||||
|
// Call instructions are vararg, but the tablegen matcher doesn't seem to
|
||||||
|
// support that, so for now we strip these extra operands.
|
||||||
|
// This is problematic if these arguments are not simple $pop stack
|
||||||
|
// registers, since e.g. a local register would get lost, so we check for
|
||||||
|
// this. This can be the case when using -disable-wasm-explicit-locals
|
||||||
|
// which currently s2wasm requires.
|
||||||
|
// TODO: Instead, we can move this code to MatchAndEmitInstruction below and
|
||||||
|
// actually generate get_local instructions on the fly.
|
||||||
|
// Or even better, improve the matcher to support vararg?
|
||||||
|
auto IsIndirect = NamePair.second == "call_indirect";
|
||||||
|
if (IsIndirect || NamePair.second == "call") {
|
||||||
|
// Figure out number of fixed operands from the instruction.
|
||||||
|
size_t CallOperands = 1; // The name token.
|
||||||
|
if (!IsIndirect) CallOperands++; // The function index.
|
||||||
|
if (!NamePair.first.empty()) CallOperands++; // The result register.
|
||||||
|
if (Operands.size() > CallOperands) {
|
||||||
|
// Ensure operands we drop are all $pop.
|
||||||
|
for (size_t I = CallOperands; I < Operands.size(); I++) {
|
||||||
|
auto Operand =
|
||||||
|
reinterpret_cast<WebAssemblyOperand *>(Operands[I].get());
|
||||||
|
if (Operand->Kind != WebAssemblyOperand::Stack)
|
||||||
|
Parser.Error(NameLoc,
|
||||||
|
"Call instruction has non-stack arguments, if this code was "
|
||||||
|
"generated with -disable-wasm-explicit-locals please remove it");
|
||||||
|
}
|
||||||
|
// Drop unneeded operands.
|
||||||
|
Operands.resize(CallOperands);
|
||||||
|
}
|
||||||
|
}
|
||||||
// Block instructions require a signature index, but these are missing in
|
// Block instructions require a signature index, but these are missing in
|
||||||
// assembly, so we add a dummy one explicitly (since we have no control
|
// assembly, so we add a dummy one explicitly (since we have no control
|
||||||
// over signature tables here, we assume these will be regenerated when
|
// over signature tables here, we assume these will be regenerated when
|
||||||
@ -281,6 +443,17 @@ public:
|
|||||||
WebAssemblyOperand::Integer, NameLoc,
|
WebAssemblyOperand::Integer, NameLoc,
|
||||||
NameLoc, WebAssemblyOperand::IntOp{-1}));
|
NameLoc, WebAssemblyOperand::IntOp{-1}));
|
||||||
}
|
}
|
||||||
|
// These don't specify the type, which has to derived from the local index.
|
||||||
|
if (NamePair.second == "get_local" || NamePair.second == "tee_local") {
|
||||||
|
if (Operands.size() >= 3 && Operands[1]->isReg() &&
|
||||||
|
Operands[2]->isImm()) {
|
||||||
|
auto Op1 = reinterpret_cast<WebAssemblyOperand *>(Operands[1].get());
|
||||||
|
auto Op2 = reinterpret_cast<WebAssemblyOperand *>(Operands[2].get());
|
||||||
|
auto Type = GetType(LocalTypes, static_cast<size_t>(Op2->Int.Val));
|
||||||
|
Op1->Reg.Type = Type;
|
||||||
|
GetType(StackTypes, Op1->Reg.RegNo) = Type;
|
||||||
|
}
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -304,6 +477,11 @@ public:
|
|||||||
IsNext(AsmToken::At) &&
|
IsNext(AsmToken::At) &&
|
||||||
Lexer.is(AsmToken::Identifier)))
|
Lexer.is(AsmToken::Identifier)))
|
||||||
return Error("Expected label,@type declaration, got: ", Lexer.getTok());
|
return Error("Expected label,@type declaration, got: ", Lexer.getTok());
|
||||||
|
if (Lexer.getTok().getString() == "function") {
|
||||||
|
// Track locals from start of function.
|
||||||
|
LocalTypes.clear();
|
||||||
|
StackTypes.clear();
|
||||||
|
}
|
||||||
Parser.Lex();
|
Parser.Lex();
|
||||||
//Out.EmitSymbolAttribute(??, MCSA_ELF_TypeFunction);
|
//Out.EmitSymbolAttribute(??, MCSA_ELF_TypeFunction);
|
||||||
} else if (DirectiveID.getString() == ".param" ||
|
} else if (DirectiveID.getString() == ".param" ||
|
||||||
@ -316,6 +494,7 @@ public:
|
|||||||
while (Lexer.is(AsmToken::Identifier)) {
|
while (Lexer.is(AsmToken::Identifier)) {
|
||||||
auto RegType = ParseRegType(Lexer.getTok().getString());
|
auto RegType = ParseRegType(Lexer.getTok().getString());
|
||||||
if (RegType == MVT::INVALID_SIMPLE_VALUE_TYPE) return true;
|
if (RegType == MVT::INVALID_SIMPLE_VALUE_TYPE) return true;
|
||||||
|
LocalTypes.push_back(RegType);
|
||||||
if (DirectiveID.getString() == ".param") {
|
if (DirectiveID.getString() == ".param") {
|
||||||
Params.push_back(RegType);
|
Params.push_back(RegType);
|
||||||
} else {
|
} else {
|
||||||
|
@ -169,54 +169,41 @@ void WebAssemblyAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
|||||||
|
|
||||||
switch (MI->getOpcode()) {
|
switch (MI->getOpcode()) {
|
||||||
case WebAssembly::ARGUMENT_I32:
|
case WebAssembly::ARGUMENT_I32:
|
||||||
case WebAssembly::ARGUMENT_I32_S:
|
|
||||||
case WebAssembly::ARGUMENT_I64:
|
case WebAssembly::ARGUMENT_I64:
|
||||||
case WebAssembly::ARGUMENT_I64_S:
|
|
||||||
case WebAssembly::ARGUMENT_F32:
|
case WebAssembly::ARGUMENT_F32:
|
||||||
case WebAssembly::ARGUMENT_F32_S:
|
|
||||||
case WebAssembly::ARGUMENT_F64:
|
case WebAssembly::ARGUMENT_F64:
|
||||||
case WebAssembly::ARGUMENT_F64_S:
|
|
||||||
case WebAssembly::ARGUMENT_v16i8:
|
case WebAssembly::ARGUMENT_v16i8:
|
||||||
case WebAssembly::ARGUMENT_v16i8_S:
|
|
||||||
case WebAssembly::ARGUMENT_v8i16:
|
case WebAssembly::ARGUMENT_v8i16:
|
||||||
case WebAssembly::ARGUMENT_v8i16_S:
|
|
||||||
case WebAssembly::ARGUMENT_v4i32:
|
case WebAssembly::ARGUMENT_v4i32:
|
||||||
case WebAssembly::ARGUMENT_v4i32_S:
|
|
||||||
case WebAssembly::ARGUMENT_v4f32:
|
case WebAssembly::ARGUMENT_v4f32:
|
||||||
case WebAssembly::ARGUMENT_v4f32_S:
|
|
||||||
// These represent values which are live into the function entry, so there's
|
// These represent values which are live into the function entry, so there's
|
||||||
// no instruction to emit.
|
// no instruction to emit.
|
||||||
break;
|
break;
|
||||||
case WebAssembly::FALLTHROUGH_RETURN_I32:
|
case WebAssembly::FALLTHROUGH_RETURN_I32:
|
||||||
case WebAssembly::FALLTHROUGH_RETURN_I32_S:
|
|
||||||
case WebAssembly::FALLTHROUGH_RETURN_I64:
|
case WebAssembly::FALLTHROUGH_RETURN_I64:
|
||||||
case WebAssembly::FALLTHROUGH_RETURN_I64_S:
|
|
||||||
case WebAssembly::FALLTHROUGH_RETURN_F32:
|
case WebAssembly::FALLTHROUGH_RETURN_F32:
|
||||||
case WebAssembly::FALLTHROUGH_RETURN_F32_S:
|
|
||||||
case WebAssembly::FALLTHROUGH_RETURN_F64:
|
case WebAssembly::FALLTHROUGH_RETURN_F64:
|
||||||
case WebAssembly::FALLTHROUGH_RETURN_F64_S:
|
|
||||||
case WebAssembly::FALLTHROUGH_RETURN_v16i8:
|
case WebAssembly::FALLTHROUGH_RETURN_v16i8:
|
||||||
case WebAssembly::FALLTHROUGH_RETURN_v16i8_S:
|
|
||||||
case WebAssembly::FALLTHROUGH_RETURN_v8i16:
|
case WebAssembly::FALLTHROUGH_RETURN_v8i16:
|
||||||
case WebAssembly::FALLTHROUGH_RETURN_v8i16_S:
|
|
||||||
case WebAssembly::FALLTHROUGH_RETURN_v4i32:
|
case WebAssembly::FALLTHROUGH_RETURN_v4i32:
|
||||||
case WebAssembly::FALLTHROUGH_RETURN_v4i32_S:
|
case WebAssembly::FALLTHROUGH_RETURN_v4f32: {
|
||||||
case WebAssembly::FALLTHROUGH_RETURN_v4f32:
|
|
||||||
case WebAssembly::FALLTHROUGH_RETURN_v4f32_S: {
|
|
||||||
// These instructions represent the implicit return at the end of a
|
// These instructions represent the implicit return at the end of a
|
||||||
// function body. Always pops one value off the stack.
|
// function body. The operand is always a pop.
|
||||||
|
assert(MFI->isVRegStackified(MI->getOperand(0).getReg()));
|
||||||
|
|
||||||
if (isVerbose()) {
|
if (isVerbose()) {
|
||||||
OutStreamer->AddComment("fallthrough-return-value");
|
OutStreamer->AddComment("fallthrough-return: $pop" +
|
||||||
|
Twine(MFI->getWARegStackId(
|
||||||
|
MFI->getWAReg(MI->getOperand(0).getReg()))));
|
||||||
OutStreamer->AddBlankLine();
|
OutStreamer->AddBlankLine();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case WebAssembly::FALLTHROUGH_RETURN_VOID:
|
case WebAssembly::FALLTHROUGH_RETURN_VOID:
|
||||||
case WebAssembly::FALLTHROUGH_RETURN_VOID_S:
|
|
||||||
// This instruction represents the implicit return at the end of a
|
// This instruction represents the implicit return at the end of a
|
||||||
// function body with no return value.
|
// function body with no return value.
|
||||||
if (isVerbose()) {
|
if (isVerbose()) {
|
||||||
OutStreamer->AddComment("fallthrough-return-void");
|
OutStreamer->AddComment("fallthrough-return");
|
||||||
OutStreamer->AddBlankLine();
|
OutStreamer->AddBlankLine();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -257,9 +244,6 @@ bool WebAssemblyAsmPrinter::PrintAsmOperand(const MachineInstr *MI,
|
|||||||
OS << MO.getImm();
|
OS << MO.getImm();
|
||||||
return false;
|
return false;
|
||||||
case MachineOperand::MO_Register:
|
case MachineOperand::MO_Register:
|
||||||
// FIXME: only opcode that still contains registers, as required by
|
|
||||||
// MachineInstr::getDebugVariable().
|
|
||||||
assert(MI->getOpcode() == WebAssembly::INLINEASM);
|
|
||||||
OS << regToString(MO);
|
OS << regToString(MO);
|
||||||
return false;
|
return false;
|
||||||
case MachineOperand::MO_GlobalAddress:
|
case MachineOperand::MO_GlobalAddress:
|
||||||
|
@ -31,21 +31,12 @@ using namespace llvm;
|
|||||||
|
|
||||||
#define DEBUG_TYPE "wasm-explicit-locals"
|
#define DEBUG_TYPE "wasm-explicit-locals"
|
||||||
|
|
||||||
// A command-line option to disable this pass, and keep implicit locals and
|
// A command-line option to disable this pass. Note that this produces output
|
||||||
// stackified registers for the purpose of testing with lit/llc ONLY.
|
// which is not valid WebAssembly, though it may be more convenient for writing
|
||||||
// This produces output which is not valid WebAssembly, and is not supported
|
// LLVM unit tests with.
|
||||||
// by assemblers/disassemblers and other MC based tools.
|
static cl::opt<bool> DisableWebAssemblyExplicitLocals(
|
||||||
static cl::opt<bool> RegisterCodeGenTestMode(
|
"disable-wasm-explicit-locals", cl::ReallyHidden,
|
||||||
"wasm-register-codegen-test-mode", cl::Hidden,
|
cl::desc("WebAssembly: Disable emission of get_local/set_local."),
|
||||||
cl::desc("WebAssembly: output stack registers and implicit locals in"
|
|
||||||
" instruction output for test purposes only."),
|
|
||||||
cl::init(false));
|
|
||||||
// This one does explicit locals but keeps stackified registers, as required
|
|
||||||
// by some current tests.
|
|
||||||
static cl::opt<bool> ExplicitLocalsCodeGenTestMode(
|
|
||||||
"wasm-explicit-locals-codegen-test-mode", cl::Hidden,
|
|
||||||
cl::desc("WebAssembly: output stack registers and explicit locals in"
|
|
||||||
" instruction output for test purposes only."),
|
|
||||||
cl::init(false));
|
cl::init(false));
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -68,8 +59,6 @@ public:
|
|||||||
};
|
};
|
||||||
} // end anonymous namespace
|
} // end anonymous namespace
|
||||||
|
|
||||||
unsigned regInstructionToStackInstruction(unsigned OpCode);
|
|
||||||
|
|
||||||
char WebAssemblyExplicitLocals::ID = 0;
|
char WebAssemblyExplicitLocals::ID = 0;
|
||||||
INITIALIZE_PASS(WebAssemblyExplicitLocals, DEBUG_TYPE,
|
INITIALIZE_PASS(WebAssemblyExplicitLocals, DEBUG_TYPE,
|
||||||
"Convert registers to WebAssembly locals", false, false)
|
"Convert registers to WebAssembly locals", false, false)
|
||||||
@ -173,7 +162,7 @@ static MVT typeForRegClass(const TargetRegisterClass *RC) {
|
|||||||
|
|
||||||
/// Given a MachineOperand of a stackified vreg, return the instruction at the
|
/// Given a MachineOperand of a stackified vreg, return the instruction at the
|
||||||
/// start of the expression tree.
|
/// start of the expression tree.
|
||||||
static MachineInstr *findStartOfTree(MachineOperand &MO,
|
static MachineInstr *FindStartOfTree(MachineOperand &MO,
|
||||||
MachineRegisterInfo &MRI,
|
MachineRegisterInfo &MRI,
|
||||||
WebAssemblyFunctionInfo &MFI) {
|
WebAssemblyFunctionInfo &MFI) {
|
||||||
unsigned Reg = MO.getReg();
|
unsigned Reg = MO.getReg();
|
||||||
@ -184,7 +173,7 @@ static MachineInstr *findStartOfTree(MachineOperand &MO,
|
|||||||
for (MachineOperand &DefMO : Def->explicit_uses()) {
|
for (MachineOperand &DefMO : Def->explicit_uses()) {
|
||||||
if (!DefMO.isReg())
|
if (!DefMO.isReg())
|
||||||
continue;
|
continue;
|
||||||
return findStartOfTree(DefMO, MRI, MFI);
|
return FindStartOfTree(DefMO, MRI, MFI);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there were no stackified uses, we've reached the start.
|
// If there were no stackified uses, we've reached the start.
|
||||||
@ -197,7 +186,7 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) {
|
|||||||
<< MF.getName() << '\n');
|
<< MF.getName() << '\n');
|
||||||
|
|
||||||
// Disable this pass if directed to do so.
|
// Disable this pass if directed to do so.
|
||||||
if (RegisterCodeGenTestMode)
|
if (DisableWebAssemblyExplicitLocals)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
bool Changed = false;
|
bool Changed = false;
|
||||||
@ -217,19 +206,19 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) {
|
|||||||
break;
|
break;
|
||||||
unsigned Reg = MI.getOperand(0).getReg();
|
unsigned Reg = MI.getOperand(0).getReg();
|
||||||
assert(!MFI.isVRegStackified(Reg));
|
assert(!MFI.isVRegStackified(Reg));
|
||||||
Reg2Local[Reg] = static_cast<unsigned>(MI.getOperand(1).getImm());
|
Reg2Local[Reg] = MI.getOperand(1).getImm();
|
||||||
MI.eraseFromParent();
|
MI.eraseFromParent();
|
||||||
Changed = true;
|
Changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start assigning local numbers after the last parameter.
|
// Start assigning local numbers after the last parameter.
|
||||||
unsigned CurLocal = static_cast<unsigned>(MFI.getParams().size());
|
unsigned CurLocal = MFI.getParams().size();
|
||||||
|
|
||||||
// Precompute the set of registers that are unused, so that we can insert
|
// Precompute the set of registers that are unused, so that we can insert
|
||||||
// drops to their defs.
|
// drops to their defs.
|
||||||
BitVector UseEmpty(MRI.getNumVirtRegs());
|
BitVector UseEmpty(MRI.getNumVirtRegs());
|
||||||
for (unsigned I = 0, E = MRI.getNumVirtRegs(); I < E; ++I)
|
for (unsigned i = 0, e = MRI.getNumVirtRegs(); i < e; ++i)
|
||||||
UseEmpty[I] = MRI.use_empty(TargetRegisterInfo::index2VirtReg(I));
|
UseEmpty[i] = MRI.use_empty(TargetRegisterInfo::index2VirtReg(i));
|
||||||
|
|
||||||
// Visit each instruction in the function.
|
// Visit each instruction in the function.
|
||||||
for (MachineBasicBlock &MBB : MF) {
|
for (MachineBasicBlock &MBB : MF) {
|
||||||
@ -333,7 +322,7 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) {
|
|||||||
// If we see a stackified register, prepare to insert subsequent
|
// If we see a stackified register, prepare to insert subsequent
|
||||||
// get_locals before the start of its tree.
|
// get_locals before the start of its tree.
|
||||||
if (MFI.isVRegStackified(OldReg)) {
|
if (MFI.isVRegStackified(OldReg)) {
|
||||||
InsertPt = findStartOfTree(MO, MRI, MFI);
|
InsertPt = FindStartOfTree(MO, MRI, MFI);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -367,410 +356,37 @@ bool WebAssemblyExplicitLocals::runOnMachineFunction(MachineFunction &MF) {
|
|||||||
Changed = true;
|
Changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ExplicitLocalsCodeGenTestMode) {
|
|
||||||
// Remove all uses of stackified registers to bring the instruction format
|
|
||||||
// into its final stack form, and transition opcodes to their _S variant.
|
|
||||||
// We do this in a seperate loop, since the previous loop adds/removes
|
|
||||||
// instructions.
|
|
||||||
// See comments in lib/Target/WebAssembly/WebAssemblyInstrFormats.td for
|
|
||||||
// details.
|
|
||||||
// TODO: the code above creates new registers which are then removed here.
|
|
||||||
// That code could be slightly simplified by not doing that, though maybe
|
|
||||||
// it is simpler conceptually to keep the code above in "register mode"
|
|
||||||
// until this transition point.
|
|
||||||
for (MachineBasicBlock::iterator I = MBB.begin(), E = MBB.end();
|
|
||||||
I != E;) {
|
|
||||||
MachineInstr &MI = *I++;
|
|
||||||
// FIXME: we are not processing inline assembly, which contains register
|
|
||||||
// operands, because it is used by later target generic code.
|
|
||||||
if (MI.isDebugInstr() || MI.isLabel() || MI.isInlineAsm())
|
|
||||||
continue;
|
|
||||||
auto RegOpcode = MI.getOpcode();
|
|
||||||
auto StackOpcode = regInstructionToStackInstruction(RegOpcode);
|
|
||||||
MI.setDesc(TII->get(StackOpcode));
|
|
||||||
// Now remove all register operands.
|
|
||||||
for (auto I = MI.getNumOperands(); I; --I) {
|
|
||||||
auto &MO = MI.getOperand(I - 1);
|
|
||||||
if (MO.isReg()) {
|
|
||||||
MI.RemoveOperand(I - 1);
|
|
||||||
// TODO: we should also update the MFI here or below to reflect the
|
|
||||||
// removed registers? The MFI is about to be deleted anyway, so
|
|
||||||
// maybe that is not worth it?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define the locals.
|
// Define the locals.
|
||||||
// TODO: Sort the locals for better compression.
|
// TODO: Sort the locals for better compression.
|
||||||
MFI.setNumLocals(CurLocal - MFI.getParams().size());
|
MFI.setNumLocals(CurLocal - MFI.getParams().size());
|
||||||
for (unsigned I = 0, E = MRI.getNumVirtRegs(); I < E; ++I) {
|
for (size_t i = 0, e = MRI.getNumVirtRegs(); i < e; ++i) {
|
||||||
unsigned Reg = TargetRegisterInfo::index2VirtReg(I);
|
unsigned Reg = TargetRegisterInfo::index2VirtReg(i);
|
||||||
auto RL = Reg2Local.find(Reg);
|
auto I = Reg2Local.find(Reg);
|
||||||
if (RL == Reg2Local.end() || RL->second < MFI.getParams().size())
|
if (I == Reg2Local.end() || I->second < MFI.getParams().size())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
MFI.setLocal(RL->second - MFI.getParams().size(),
|
MFI.setLocal(I->second - MFI.getParams().size(),
|
||||||
typeForRegClass(MRI.getRegClass(Reg)));
|
typeForRegClass(MRI.getRegClass(Reg)));
|
||||||
Changed = true;
|
Changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef NDEBUG
|
||||||
|
// Assert that all registers have been stackified at this point.
|
||||||
|
for (const MachineBasicBlock &MBB : MF) {
|
||||||
|
for (const MachineInstr &MI : MBB) {
|
||||||
|
if (MI.isDebugInstr() || MI.isLabel())
|
||||||
|
continue;
|
||||||
|
for (const MachineOperand &MO : MI.explicit_operands()) {
|
||||||
|
assert(
|
||||||
|
(!MO.isReg() || MRI.use_empty(MO.getReg()) ||
|
||||||
|
MFI.isVRegStackified(MO.getReg())) &&
|
||||||
|
"WebAssemblyExplicitLocals failed to stackify a register operand");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return Changed;
|
return Changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned regInstructionToStackInstruction(unsigned OpCode) {
|
|
||||||
switch (OpCode) {
|
|
||||||
default:
|
|
||||||
// You may hit this if you add new instructions, please add them below.
|
|
||||||
// For most of these opcodes, this function could have been implemented
|
|
||||||
// as "return OpCode + 1", but since table-gen alphabetically sorts them,
|
|
||||||
// this cannot be guaranteed (see e.g. BR and BR_IF).
|
|
||||||
// The approach below is the same as what the x87 backend does.
|
|
||||||
// TODO(wvo): to make this code cleaner, create a custom tablegen
|
|
||||||
// code generator that emits the table below automatically.
|
|
||||||
llvm_unreachable(
|
|
||||||
"unknown WebAssembly instruction in Explicit Locals pass");
|
|
||||||
case WebAssembly::ABS_F32: return WebAssembly::ABS_F32_S;
|
|
||||||
case WebAssembly::ABS_F64: return WebAssembly::ABS_F64_S;
|
|
||||||
case WebAssembly::ADD_F32: return WebAssembly::ADD_F32_S;
|
|
||||||
case WebAssembly::ADD_F32x4: return WebAssembly::ADD_F32x4_S;
|
|
||||||
case WebAssembly::ADD_F64: return WebAssembly::ADD_F64_S;
|
|
||||||
case WebAssembly::ADD_I16x8: return WebAssembly::ADD_I16x8_S;
|
|
||||||
case WebAssembly::ADD_I32: return WebAssembly::ADD_I32_S;
|
|
||||||
case WebAssembly::ADD_I32x4: return WebAssembly::ADD_I32x4_S;
|
|
||||||
case WebAssembly::ADD_I64: return WebAssembly::ADD_I64_S;
|
|
||||||
case WebAssembly::ADD_I8x16: return WebAssembly::ADD_I8x16_S;
|
|
||||||
case WebAssembly::ADJCALLSTACKDOWN: return WebAssembly::ADJCALLSTACKDOWN_S;
|
|
||||||
case WebAssembly::ADJCALLSTACKUP: return WebAssembly::ADJCALLSTACKUP_S;
|
|
||||||
case WebAssembly::AND_I32: return WebAssembly::AND_I32_S;
|
|
||||||
case WebAssembly::AND_I64: return WebAssembly::AND_I64_S;
|
|
||||||
case WebAssembly::ARGUMENT_EXCEPT_REF: return WebAssembly::ARGUMENT_EXCEPT_REF_S;
|
|
||||||
case WebAssembly::ARGUMENT_F32: return WebAssembly::ARGUMENT_F32_S;
|
|
||||||
case WebAssembly::ARGUMENT_F64: return WebAssembly::ARGUMENT_F64_S;
|
|
||||||
case WebAssembly::ARGUMENT_I32: return WebAssembly::ARGUMENT_I32_S;
|
|
||||||
case WebAssembly::ARGUMENT_I64: return WebAssembly::ARGUMENT_I64_S;
|
|
||||||
case WebAssembly::ARGUMENT_v16i8: return WebAssembly::ARGUMENT_v16i8_S;
|
|
||||||
case WebAssembly::ARGUMENT_v4f32: return WebAssembly::ARGUMENT_v4f32_S;
|
|
||||||
case WebAssembly::ARGUMENT_v4i32: return WebAssembly::ARGUMENT_v4i32_S;
|
|
||||||
case WebAssembly::ARGUMENT_v8i16: return WebAssembly::ARGUMENT_v8i16_S;
|
|
||||||
case WebAssembly::ATOMIC_LOAD16_U_I32: return WebAssembly::ATOMIC_LOAD16_U_I32_S;
|
|
||||||
case WebAssembly::ATOMIC_LOAD16_U_I64: return WebAssembly::ATOMIC_LOAD16_U_I64_S;
|
|
||||||
case WebAssembly::ATOMIC_LOAD32_U_I64: return WebAssembly::ATOMIC_LOAD32_U_I64_S;
|
|
||||||
case WebAssembly::ATOMIC_LOAD8_U_I32: return WebAssembly::ATOMIC_LOAD8_U_I32_S;
|
|
||||||
case WebAssembly::ATOMIC_LOAD8_U_I64: return WebAssembly::ATOMIC_LOAD8_U_I64_S;
|
|
||||||
case WebAssembly::ATOMIC_LOAD_I32: return WebAssembly::ATOMIC_LOAD_I32_S;
|
|
||||||
case WebAssembly::ATOMIC_LOAD_I64: return WebAssembly::ATOMIC_LOAD_I64_S;
|
|
||||||
case WebAssembly::ATOMIC_STORE16_I32: return WebAssembly::ATOMIC_STORE16_I32_S;
|
|
||||||
case WebAssembly::ATOMIC_STORE16_I64: return WebAssembly::ATOMIC_STORE16_I64_S;
|
|
||||||
case WebAssembly::ATOMIC_STORE32_I64: return WebAssembly::ATOMIC_STORE32_I64_S;
|
|
||||||
case WebAssembly::ATOMIC_STORE8_I32: return WebAssembly::ATOMIC_STORE8_I32_S;
|
|
||||||
case WebAssembly::ATOMIC_STORE8_I64: return WebAssembly::ATOMIC_STORE8_I64_S;
|
|
||||||
case WebAssembly::ATOMIC_STORE_I32: return WebAssembly::ATOMIC_STORE_I32_S;
|
|
||||||
case WebAssembly::ATOMIC_STORE_I64: return WebAssembly::ATOMIC_STORE_I64_S;
|
|
||||||
case WebAssembly::BLOCK: return WebAssembly::BLOCK_S;
|
|
||||||
case WebAssembly::BR: return WebAssembly::BR_S;
|
|
||||||
case WebAssembly::BR_IF: return WebAssembly::BR_IF_S;
|
|
||||||
case WebAssembly::BR_TABLE_I32: return WebAssembly::BR_TABLE_I32_S;
|
|
||||||
case WebAssembly::BR_TABLE_I64: return WebAssembly::BR_TABLE_I64_S;
|
|
||||||
case WebAssembly::BR_UNLESS: return WebAssembly::BR_UNLESS_S;
|
|
||||||
case WebAssembly::CALL_EXCEPT_REF: return WebAssembly::CALL_EXCEPT_REF_S;
|
|
||||||
case WebAssembly::CALL_F32: return WebAssembly::CALL_F32_S;
|
|
||||||
case WebAssembly::CALL_F64: return WebAssembly::CALL_F64_S;
|
|
||||||
case WebAssembly::CALL_I32: return WebAssembly::CALL_I32_S;
|
|
||||||
case WebAssembly::CALL_I64: return WebAssembly::CALL_I64_S;
|
|
||||||
case WebAssembly::CALL_INDIRECT_EXCEPT_REF: return WebAssembly::CALL_INDIRECT_EXCEPT_REF_S;
|
|
||||||
case WebAssembly::CALL_INDIRECT_F32: return WebAssembly::CALL_INDIRECT_F32_S;
|
|
||||||
case WebAssembly::CALL_INDIRECT_F64: return WebAssembly::CALL_INDIRECT_F64_S;
|
|
||||||
case WebAssembly::CALL_INDIRECT_I32: return WebAssembly::CALL_INDIRECT_I32_S;
|
|
||||||
case WebAssembly::CALL_INDIRECT_I64: return WebAssembly::CALL_INDIRECT_I64_S;
|
|
||||||
case WebAssembly::CALL_INDIRECT_VOID: return WebAssembly::CALL_INDIRECT_VOID_S;
|
|
||||||
case WebAssembly::CALL_INDIRECT_v16i8: return WebAssembly::CALL_INDIRECT_v16i8_S;
|
|
||||||
case WebAssembly::CALL_INDIRECT_v4f32: return WebAssembly::CALL_INDIRECT_v4f32_S;
|
|
||||||
case WebAssembly::CALL_INDIRECT_v4i32: return WebAssembly::CALL_INDIRECT_v4i32_S;
|
|
||||||
case WebAssembly::CALL_INDIRECT_v8i16: return WebAssembly::CALL_INDIRECT_v8i16_S;
|
|
||||||
case WebAssembly::CALL_VOID: return WebAssembly::CALL_VOID_S;
|
|
||||||
case WebAssembly::CALL_v16i8: return WebAssembly::CALL_v16i8_S;
|
|
||||||
case WebAssembly::CALL_v4f32: return WebAssembly::CALL_v4f32_S;
|
|
||||||
case WebAssembly::CALL_v4i32: return WebAssembly::CALL_v4i32_S;
|
|
||||||
case WebAssembly::CALL_v8i16: return WebAssembly::CALL_v8i16_S;
|
|
||||||
case WebAssembly::CATCHRET: return WebAssembly::CATCHRET_S;
|
|
||||||
case WebAssembly::CATCH_ALL: return WebAssembly::CATCH_ALL_S;
|
|
||||||
case WebAssembly::CATCH_I32: return WebAssembly::CATCH_I32_S;
|
|
||||||
case WebAssembly::CATCH_I64: return WebAssembly::CATCH_I64_S;
|
|
||||||
case WebAssembly::CEIL_F32: return WebAssembly::CEIL_F32_S;
|
|
||||||
case WebAssembly::CEIL_F64: return WebAssembly::CEIL_F64_S;
|
|
||||||
case WebAssembly::CLEANUPRET: return WebAssembly::CLEANUPRET_S;
|
|
||||||
case WebAssembly::CLZ_I32: return WebAssembly::CLZ_I32_S;
|
|
||||||
case WebAssembly::CLZ_I64: return WebAssembly::CLZ_I64_S;
|
|
||||||
case WebAssembly::CONST_F32: return WebAssembly::CONST_F32_S;
|
|
||||||
case WebAssembly::CONST_F64: return WebAssembly::CONST_F64_S;
|
|
||||||
case WebAssembly::CONST_I32: return WebAssembly::CONST_I32_S;
|
|
||||||
case WebAssembly::CONST_I64: return WebAssembly::CONST_I64_S;
|
|
||||||
case WebAssembly::COPYSIGN_F32: return WebAssembly::COPYSIGN_F32_S;
|
|
||||||
case WebAssembly::COPYSIGN_F64: return WebAssembly::COPYSIGN_F64_S;
|
|
||||||
case WebAssembly::COPY_EXCEPT_REF: return WebAssembly::COPY_EXCEPT_REF_S;
|
|
||||||
case WebAssembly::COPY_F32: return WebAssembly::COPY_F32_S;
|
|
||||||
case WebAssembly::COPY_F64: return WebAssembly::COPY_F64_S;
|
|
||||||
case WebAssembly::COPY_I32: return WebAssembly::COPY_I32_S;
|
|
||||||
case WebAssembly::COPY_I64: return WebAssembly::COPY_I64_S;
|
|
||||||
case WebAssembly::COPY_V128: return WebAssembly::COPY_V128_S;
|
|
||||||
case WebAssembly::CTZ_I32: return WebAssembly::CTZ_I32_S;
|
|
||||||
case WebAssembly::CTZ_I64: return WebAssembly::CTZ_I64_S;
|
|
||||||
case WebAssembly::CURRENT_MEMORY_I32: return WebAssembly::CURRENT_MEMORY_I32_S;
|
|
||||||
case WebAssembly::DIV_F32: return WebAssembly::DIV_F32_S;
|
|
||||||
case WebAssembly::DIV_F64: return WebAssembly::DIV_F64_S;
|
|
||||||
case WebAssembly::DIV_S_I32: return WebAssembly::DIV_S_I32_S;
|
|
||||||
case WebAssembly::DIV_S_I64: return WebAssembly::DIV_S_I64_S;
|
|
||||||
case WebAssembly::DIV_U_I32: return WebAssembly::DIV_U_I32_S;
|
|
||||||
case WebAssembly::DIV_U_I64: return WebAssembly::DIV_U_I64_S;
|
|
||||||
case WebAssembly::DROP_EXCEPT_REF: return WebAssembly::DROP_EXCEPT_REF_S;
|
|
||||||
case WebAssembly::DROP_F32: return WebAssembly::DROP_F32_S;
|
|
||||||
case WebAssembly::DROP_F64: return WebAssembly::DROP_F64_S;
|
|
||||||
case WebAssembly::DROP_I32: return WebAssembly::DROP_I32_S;
|
|
||||||
case WebAssembly::DROP_I64: return WebAssembly::DROP_I64_S;
|
|
||||||
case WebAssembly::DROP_V128: return WebAssembly::DROP_V128_S;
|
|
||||||
case WebAssembly::END_BLOCK: return WebAssembly::END_BLOCK_S;
|
|
||||||
case WebAssembly::END_FUNCTION: return WebAssembly::END_FUNCTION_S;
|
|
||||||
case WebAssembly::END_LOOP: return WebAssembly::END_LOOP_S;
|
|
||||||
case WebAssembly::END_TRY: return WebAssembly::END_TRY_S;
|
|
||||||
case WebAssembly::EQZ_I32: return WebAssembly::EQZ_I32_S;
|
|
||||||
case WebAssembly::EQZ_I64: return WebAssembly::EQZ_I64_S;
|
|
||||||
case WebAssembly::EQ_F32: return WebAssembly::EQ_F32_S;
|
|
||||||
case WebAssembly::EQ_F64: return WebAssembly::EQ_F64_S;
|
|
||||||
case WebAssembly::EQ_I32: return WebAssembly::EQ_I32_S;
|
|
||||||
case WebAssembly::EQ_I64: return WebAssembly::EQ_I64_S;
|
|
||||||
case WebAssembly::F32_CONVERT_S_I32: return WebAssembly::F32_CONVERT_S_I32_S;
|
|
||||||
case WebAssembly::F32_CONVERT_S_I64: return WebAssembly::F32_CONVERT_S_I64_S;
|
|
||||||
case WebAssembly::F32_CONVERT_U_I32: return WebAssembly::F32_CONVERT_U_I32_S;
|
|
||||||
case WebAssembly::F32_CONVERT_U_I64: return WebAssembly::F32_CONVERT_U_I64_S;
|
|
||||||
case WebAssembly::F32_DEMOTE_F64: return WebAssembly::F32_DEMOTE_F64_S;
|
|
||||||
case WebAssembly::F32_REINTERPRET_I32: return WebAssembly::F32_REINTERPRET_I32_S;
|
|
||||||
case WebAssembly::F64_CONVERT_S_I32: return WebAssembly::F64_CONVERT_S_I32_S;
|
|
||||||
case WebAssembly::F64_CONVERT_S_I64: return WebAssembly::F64_CONVERT_S_I64_S;
|
|
||||||
case WebAssembly::F64_CONVERT_U_I32: return WebAssembly::F64_CONVERT_U_I32_S;
|
|
||||||
case WebAssembly::F64_CONVERT_U_I64: return WebAssembly::F64_CONVERT_U_I64_S;
|
|
||||||
case WebAssembly::F64_PROMOTE_F32: return WebAssembly::F64_PROMOTE_F32_S;
|
|
||||||
case WebAssembly::F64_REINTERPRET_I64: return WebAssembly::F64_REINTERPRET_I64_S;
|
|
||||||
case WebAssembly::FALLTHROUGH_RETURN_EXCEPT_REF: return WebAssembly::FALLTHROUGH_RETURN_EXCEPT_REF_S;
|
|
||||||
case WebAssembly::FALLTHROUGH_RETURN_F32: return WebAssembly::FALLTHROUGH_RETURN_F32_S;
|
|
||||||
case WebAssembly::FALLTHROUGH_RETURN_F64: return WebAssembly::FALLTHROUGH_RETURN_F64_S;
|
|
||||||
case WebAssembly::FALLTHROUGH_RETURN_I32: return WebAssembly::FALLTHROUGH_RETURN_I32_S;
|
|
||||||
case WebAssembly::FALLTHROUGH_RETURN_I64: return WebAssembly::FALLTHROUGH_RETURN_I64_S;
|
|
||||||
case WebAssembly::FALLTHROUGH_RETURN_VOID: return WebAssembly::FALLTHROUGH_RETURN_VOID_S;
|
|
||||||
case WebAssembly::FALLTHROUGH_RETURN_v16i8: return WebAssembly::FALLTHROUGH_RETURN_v16i8_S;
|
|
||||||
case WebAssembly::FALLTHROUGH_RETURN_v4f32: return WebAssembly::FALLTHROUGH_RETURN_v4f32_S;
|
|
||||||
case WebAssembly::FALLTHROUGH_RETURN_v4i32: return WebAssembly::FALLTHROUGH_RETURN_v4i32_S;
|
|
||||||
case WebAssembly::FALLTHROUGH_RETURN_v8i16: return WebAssembly::FALLTHROUGH_RETURN_v8i16_S;
|
|
||||||
case WebAssembly::FLOOR_F32: return WebAssembly::FLOOR_F32_S;
|
|
||||||
case WebAssembly::FLOOR_F64: return WebAssembly::FLOOR_F64_S;
|
|
||||||
case WebAssembly::FP_TO_SINT_I32_F32: return WebAssembly::FP_TO_SINT_I32_F32_S;
|
|
||||||
case WebAssembly::FP_TO_SINT_I32_F64: return WebAssembly::FP_TO_SINT_I32_F64_S;
|
|
||||||
case WebAssembly::FP_TO_SINT_I64_F32: return WebAssembly::FP_TO_SINT_I64_F32_S;
|
|
||||||
case WebAssembly::FP_TO_SINT_I64_F64: return WebAssembly::FP_TO_SINT_I64_F64_S;
|
|
||||||
case WebAssembly::FP_TO_UINT_I32_F32: return WebAssembly::FP_TO_UINT_I32_F32_S;
|
|
||||||
case WebAssembly::FP_TO_UINT_I32_F64: return WebAssembly::FP_TO_UINT_I32_F64_S;
|
|
||||||
case WebAssembly::FP_TO_UINT_I64_F32: return WebAssembly::FP_TO_UINT_I64_F32_S;
|
|
||||||
case WebAssembly::FP_TO_UINT_I64_F64: return WebAssembly::FP_TO_UINT_I64_F64_S;
|
|
||||||
case WebAssembly::GET_GLOBAL_EXCEPT_REF: return WebAssembly::GET_GLOBAL_EXCEPT_REF_S;
|
|
||||||
case WebAssembly::GET_GLOBAL_F32: return WebAssembly::GET_GLOBAL_F32_S;
|
|
||||||
case WebAssembly::GET_GLOBAL_F64: return WebAssembly::GET_GLOBAL_F64_S;
|
|
||||||
case WebAssembly::GET_GLOBAL_I32: return WebAssembly::GET_GLOBAL_I32_S;
|
|
||||||
case WebAssembly::GET_GLOBAL_I64: return WebAssembly::GET_GLOBAL_I64_S;
|
|
||||||
case WebAssembly::GET_GLOBAL_V128: return WebAssembly::GET_GLOBAL_V128_S;
|
|
||||||
case WebAssembly::GET_LOCAL_EXCEPT_REF: return WebAssembly::GET_LOCAL_EXCEPT_REF_S;
|
|
||||||
case WebAssembly::GET_LOCAL_F32: return WebAssembly::GET_LOCAL_F32_S;
|
|
||||||
case WebAssembly::GET_LOCAL_F64: return WebAssembly::GET_LOCAL_F64_S;
|
|
||||||
case WebAssembly::GET_LOCAL_I32: return WebAssembly::GET_LOCAL_I32_S;
|
|
||||||
case WebAssembly::GET_LOCAL_I64: return WebAssembly::GET_LOCAL_I64_S;
|
|
||||||
case WebAssembly::GET_LOCAL_V128: return WebAssembly::GET_LOCAL_V128_S;
|
|
||||||
case WebAssembly::GE_F32: return WebAssembly::GE_F32_S;
|
|
||||||
case WebAssembly::GE_F64: return WebAssembly::GE_F64_S;
|
|
||||||
case WebAssembly::GE_S_I32: return WebAssembly::GE_S_I32_S;
|
|
||||||
case WebAssembly::GE_S_I64: return WebAssembly::GE_S_I64_S;
|
|
||||||
case WebAssembly::GE_U_I32: return WebAssembly::GE_U_I32_S;
|
|
||||||
case WebAssembly::GE_U_I64: return WebAssembly::GE_U_I64_S;
|
|
||||||
case WebAssembly::GROW_MEMORY_I32: return WebAssembly::GROW_MEMORY_I32_S;
|
|
||||||
case WebAssembly::GT_F32: return WebAssembly::GT_F32_S;
|
|
||||||
case WebAssembly::GT_F64: return WebAssembly::GT_F64_S;
|
|
||||||
case WebAssembly::GT_S_I32: return WebAssembly::GT_S_I32_S;
|
|
||||||
case WebAssembly::GT_S_I64: return WebAssembly::GT_S_I64_S;
|
|
||||||
case WebAssembly::GT_U_I32: return WebAssembly::GT_U_I32_S;
|
|
||||||
case WebAssembly::GT_U_I64: return WebAssembly::GT_U_I64_S;
|
|
||||||
case WebAssembly::I32_EXTEND16_S_I32: return WebAssembly::I32_EXTEND16_S_I32_S;
|
|
||||||
case WebAssembly::I32_EXTEND8_S_I32: return WebAssembly::I32_EXTEND8_S_I32_S;
|
|
||||||
case WebAssembly::I32_REINTERPRET_F32: return WebAssembly::I32_REINTERPRET_F32_S;
|
|
||||||
case WebAssembly::I32_TRUNC_S_F32: return WebAssembly::I32_TRUNC_S_F32_S;
|
|
||||||
case WebAssembly::I32_TRUNC_S_F64: return WebAssembly::I32_TRUNC_S_F64_S;
|
|
||||||
case WebAssembly::I32_TRUNC_S_SAT_F32: return WebAssembly::I32_TRUNC_S_SAT_F32_S;
|
|
||||||
case WebAssembly::I32_TRUNC_S_SAT_F64: return WebAssembly::I32_TRUNC_S_SAT_F64_S;
|
|
||||||
case WebAssembly::I32_TRUNC_U_F32: return WebAssembly::I32_TRUNC_U_F32_S;
|
|
||||||
case WebAssembly::I32_TRUNC_U_F64: return WebAssembly::I32_TRUNC_U_F64_S;
|
|
||||||
case WebAssembly::I32_TRUNC_U_SAT_F32: return WebAssembly::I32_TRUNC_U_SAT_F32_S;
|
|
||||||
case WebAssembly::I32_TRUNC_U_SAT_F64: return WebAssembly::I32_TRUNC_U_SAT_F64_S;
|
|
||||||
case WebAssembly::I32_WRAP_I64: return WebAssembly::I32_WRAP_I64_S;
|
|
||||||
case WebAssembly::I64_EXTEND16_S_I64: return WebAssembly::I64_EXTEND16_S_I64_S;
|
|
||||||
case WebAssembly::I64_EXTEND32_S_I64: return WebAssembly::I64_EXTEND32_S_I64_S;
|
|
||||||
case WebAssembly::I64_EXTEND8_S_I64: return WebAssembly::I64_EXTEND8_S_I64_S;
|
|
||||||
case WebAssembly::I64_EXTEND_S_I32: return WebAssembly::I64_EXTEND_S_I32_S;
|
|
||||||
case WebAssembly::I64_EXTEND_U_I32: return WebAssembly::I64_EXTEND_U_I32_S;
|
|
||||||
case WebAssembly::I64_REINTERPRET_F64: return WebAssembly::I64_REINTERPRET_F64_S;
|
|
||||||
case WebAssembly::I64_TRUNC_S_F32: return WebAssembly::I64_TRUNC_S_F32_S;
|
|
||||||
case WebAssembly::I64_TRUNC_S_F64: return WebAssembly::I64_TRUNC_S_F64_S;
|
|
||||||
case WebAssembly::I64_TRUNC_S_SAT_F32: return WebAssembly::I64_TRUNC_S_SAT_F32_S;
|
|
||||||
case WebAssembly::I64_TRUNC_S_SAT_F64: return WebAssembly::I64_TRUNC_S_SAT_F64_S;
|
|
||||||
case WebAssembly::I64_TRUNC_U_F32: return WebAssembly::I64_TRUNC_U_F32_S;
|
|
||||||
case WebAssembly::I64_TRUNC_U_F64: return WebAssembly::I64_TRUNC_U_F64_S;
|
|
||||||
case WebAssembly::I64_TRUNC_U_SAT_F32: return WebAssembly::I64_TRUNC_U_SAT_F32_S;
|
|
||||||
case WebAssembly::I64_TRUNC_U_SAT_F64: return WebAssembly::I64_TRUNC_U_SAT_F64_S;
|
|
||||||
case WebAssembly::LE_F32: return WebAssembly::LE_F32_S;
|
|
||||||
case WebAssembly::LE_F64: return WebAssembly::LE_F64_S;
|
|
||||||
case WebAssembly::LE_S_I32: return WebAssembly::LE_S_I32_S;
|
|
||||||
case WebAssembly::LE_S_I64: return WebAssembly::LE_S_I64_S;
|
|
||||||
case WebAssembly::LE_U_I32: return WebAssembly::LE_U_I32_S;
|
|
||||||
case WebAssembly::LE_U_I64: return WebAssembly::LE_U_I64_S;
|
|
||||||
case WebAssembly::LOAD16_S_I32: return WebAssembly::LOAD16_S_I32_S;
|
|
||||||
case WebAssembly::LOAD16_S_I64: return WebAssembly::LOAD16_S_I64_S;
|
|
||||||
case WebAssembly::LOAD16_U_I32: return WebAssembly::LOAD16_U_I32_S;
|
|
||||||
case WebAssembly::LOAD16_U_I64: return WebAssembly::LOAD16_U_I64_S;
|
|
||||||
case WebAssembly::LOAD32_S_I64: return WebAssembly::LOAD32_S_I64_S;
|
|
||||||
case WebAssembly::LOAD32_U_I64: return WebAssembly::LOAD32_U_I64_S;
|
|
||||||
case WebAssembly::LOAD8_S_I32: return WebAssembly::LOAD8_S_I32_S;
|
|
||||||
case WebAssembly::LOAD8_S_I64: return WebAssembly::LOAD8_S_I64_S;
|
|
||||||
case WebAssembly::LOAD8_U_I32: return WebAssembly::LOAD8_U_I32_S;
|
|
||||||
case WebAssembly::LOAD8_U_I64: return WebAssembly::LOAD8_U_I64_S;
|
|
||||||
case WebAssembly::LOAD_F32: return WebAssembly::LOAD_F32_S;
|
|
||||||
case WebAssembly::LOAD_F64: return WebAssembly::LOAD_F64_S;
|
|
||||||
case WebAssembly::LOAD_I32: return WebAssembly::LOAD_I32_S;
|
|
||||||
case WebAssembly::LOAD_I64: return WebAssembly::LOAD_I64_S;
|
|
||||||
case WebAssembly::LOOP: return WebAssembly::LOOP_S;
|
|
||||||
case WebAssembly::LT_F32: return WebAssembly::LT_F32_S;
|
|
||||||
case WebAssembly::LT_F64: return WebAssembly::LT_F64_S;
|
|
||||||
case WebAssembly::LT_S_I32: return WebAssembly::LT_S_I32_S;
|
|
||||||
case WebAssembly::LT_S_I64: return WebAssembly::LT_S_I64_S;
|
|
||||||
case WebAssembly::LT_U_I32: return WebAssembly::LT_U_I32_S;
|
|
||||||
case WebAssembly::LT_U_I64: return WebAssembly::LT_U_I64_S;
|
|
||||||
case WebAssembly::MAX_F32: return WebAssembly::MAX_F32_S;
|
|
||||||
case WebAssembly::MAX_F64: return WebAssembly::MAX_F64_S;
|
|
||||||
case WebAssembly::MEMORY_GROW_I32: return WebAssembly::MEMORY_GROW_I32_S;
|
|
||||||
case WebAssembly::MEMORY_SIZE_I32: return WebAssembly::MEMORY_SIZE_I32_S;
|
|
||||||
case WebAssembly::MEM_GROW_I32: return WebAssembly::MEM_GROW_I32_S;
|
|
||||||
case WebAssembly::MEM_SIZE_I32: return WebAssembly::MEM_SIZE_I32_S;
|
|
||||||
case WebAssembly::MIN_F32: return WebAssembly::MIN_F32_S;
|
|
||||||
case WebAssembly::MIN_F64: return WebAssembly::MIN_F64_S;
|
|
||||||
case WebAssembly::MUL_F32: return WebAssembly::MUL_F32_S;
|
|
||||||
case WebAssembly::MUL_F32x4: return WebAssembly::MUL_F32x4_S;
|
|
||||||
case WebAssembly::MUL_F64: return WebAssembly::MUL_F64_S;
|
|
||||||
case WebAssembly::MUL_I16x8: return WebAssembly::MUL_I16x8_S;
|
|
||||||
case WebAssembly::MUL_I32: return WebAssembly::MUL_I32_S;
|
|
||||||
case WebAssembly::MUL_I32x4: return WebAssembly::MUL_I32x4_S;
|
|
||||||
case WebAssembly::MUL_I64: return WebAssembly::MUL_I64_S;
|
|
||||||
case WebAssembly::MUL_I8x16: return WebAssembly::MUL_I8x16_S;
|
|
||||||
case WebAssembly::NEAREST_F32: return WebAssembly::NEAREST_F32_S;
|
|
||||||
case WebAssembly::NEAREST_F64: return WebAssembly::NEAREST_F64_S;
|
|
||||||
case WebAssembly::NEG_F32: return WebAssembly::NEG_F32_S;
|
|
||||||
case WebAssembly::NEG_F64: return WebAssembly::NEG_F64_S;
|
|
||||||
case WebAssembly::NE_F32: return WebAssembly::NE_F32_S;
|
|
||||||
case WebAssembly::NE_F64: return WebAssembly::NE_F64_S;
|
|
||||||
case WebAssembly::NE_I32: return WebAssembly::NE_I32_S;
|
|
||||||
case WebAssembly::NE_I64: return WebAssembly::NE_I64_S;
|
|
||||||
case WebAssembly::NOP: return WebAssembly::NOP_S;
|
|
||||||
case WebAssembly::OR_I32: return WebAssembly::OR_I32_S;
|
|
||||||
case WebAssembly::OR_I64: return WebAssembly::OR_I64_S;
|
|
||||||
case WebAssembly::PCALL_INDIRECT_EXCEPT_REF: return WebAssembly::PCALL_INDIRECT_EXCEPT_REF_S;
|
|
||||||
case WebAssembly::PCALL_INDIRECT_F32: return WebAssembly::PCALL_INDIRECT_F32_S;
|
|
||||||
case WebAssembly::PCALL_INDIRECT_F64: return WebAssembly::PCALL_INDIRECT_F64_S;
|
|
||||||
case WebAssembly::PCALL_INDIRECT_I32: return WebAssembly::PCALL_INDIRECT_I32_S;
|
|
||||||
case WebAssembly::PCALL_INDIRECT_I64: return WebAssembly::PCALL_INDIRECT_I64_S;
|
|
||||||
case WebAssembly::PCALL_INDIRECT_VOID: return WebAssembly::PCALL_INDIRECT_VOID_S;
|
|
||||||
case WebAssembly::PCALL_INDIRECT_v16i8: return WebAssembly::PCALL_INDIRECT_v16i8_S;
|
|
||||||
case WebAssembly::PCALL_INDIRECT_v4f32: return WebAssembly::PCALL_INDIRECT_v4f32_S;
|
|
||||||
case WebAssembly::PCALL_INDIRECT_v4i32: return WebAssembly::PCALL_INDIRECT_v4i32_S;
|
|
||||||
case WebAssembly::PCALL_INDIRECT_v8i16: return WebAssembly::PCALL_INDIRECT_v8i16_S;
|
|
||||||
case WebAssembly::POPCNT_I32: return WebAssembly::POPCNT_I32_S;
|
|
||||||
case WebAssembly::POPCNT_I64: return WebAssembly::POPCNT_I64_S;
|
|
||||||
case WebAssembly::REM_S_I32: return WebAssembly::REM_S_I32_S;
|
|
||||||
case WebAssembly::REM_S_I64: return WebAssembly::REM_S_I64_S;
|
|
||||||
case WebAssembly::REM_U_I32: return WebAssembly::REM_U_I32_S;
|
|
||||||
case WebAssembly::REM_U_I64: return WebAssembly::REM_U_I64_S;
|
|
||||||
case WebAssembly::RETHROW: return WebAssembly::RETHROW_S;
|
|
||||||
case WebAssembly::RETHROW_TO_CALLER: return WebAssembly::RETHROW_TO_CALLER_S;
|
|
||||||
case WebAssembly::RETURN_EXCEPT_REF: return WebAssembly::RETURN_EXCEPT_REF_S;
|
|
||||||
case WebAssembly::RETURN_F32: return WebAssembly::RETURN_F32_S;
|
|
||||||
case WebAssembly::RETURN_F64: return WebAssembly::RETURN_F64_S;
|
|
||||||
case WebAssembly::RETURN_I32: return WebAssembly::RETURN_I32_S;
|
|
||||||
case WebAssembly::RETURN_I64: return WebAssembly::RETURN_I64_S;
|
|
||||||
case WebAssembly::RETURN_VOID: return WebAssembly::RETURN_VOID_S;
|
|
||||||
case WebAssembly::RETURN_v16i8: return WebAssembly::RETURN_v16i8_S;
|
|
||||||
case WebAssembly::RETURN_v4f32: return WebAssembly::RETURN_v4f32_S;
|
|
||||||
case WebAssembly::RETURN_v4i32: return WebAssembly::RETURN_v4i32_S;
|
|
||||||
case WebAssembly::RETURN_v8i16: return WebAssembly::RETURN_v8i16_S;
|
|
||||||
case WebAssembly::ROTL_I32: return WebAssembly::ROTL_I32_S;
|
|
||||||
case WebAssembly::ROTL_I64: return WebAssembly::ROTL_I64_S;
|
|
||||||
case WebAssembly::ROTR_I32: return WebAssembly::ROTR_I32_S;
|
|
||||||
case WebAssembly::ROTR_I64: return WebAssembly::ROTR_I64_S;
|
|
||||||
case WebAssembly::SELECT_EXCEPT_REF: return WebAssembly::SELECT_EXCEPT_REF_S;
|
|
||||||
case WebAssembly::SELECT_F32: return WebAssembly::SELECT_F32_S;
|
|
||||||
case WebAssembly::SELECT_F64: return WebAssembly::SELECT_F64_S;
|
|
||||||
case WebAssembly::SELECT_I32: return WebAssembly::SELECT_I32_S;
|
|
||||||
case WebAssembly::SELECT_I64: return WebAssembly::SELECT_I64_S;
|
|
||||||
case WebAssembly::SET_GLOBAL_EXCEPT_REF: return WebAssembly::SET_GLOBAL_EXCEPT_REF_S;
|
|
||||||
case WebAssembly::SET_GLOBAL_F32: return WebAssembly::SET_GLOBAL_F32_S;
|
|
||||||
case WebAssembly::SET_GLOBAL_F64: return WebAssembly::SET_GLOBAL_F64_S;
|
|
||||||
case WebAssembly::SET_GLOBAL_I32: return WebAssembly::SET_GLOBAL_I32_S;
|
|
||||||
case WebAssembly::SET_GLOBAL_I64: return WebAssembly::SET_GLOBAL_I64_S;
|
|
||||||
case WebAssembly::SET_GLOBAL_V128: return WebAssembly::SET_GLOBAL_V128_S;
|
|
||||||
case WebAssembly::SET_LOCAL_EXCEPT_REF: return WebAssembly::SET_LOCAL_EXCEPT_REF_S;
|
|
||||||
case WebAssembly::SET_LOCAL_F32: return WebAssembly::SET_LOCAL_F32_S;
|
|
||||||
case WebAssembly::SET_LOCAL_F64: return WebAssembly::SET_LOCAL_F64_S;
|
|
||||||
case WebAssembly::SET_LOCAL_I32: return WebAssembly::SET_LOCAL_I32_S;
|
|
||||||
case WebAssembly::SET_LOCAL_I64: return WebAssembly::SET_LOCAL_I64_S;
|
|
||||||
case WebAssembly::SET_LOCAL_V128: return WebAssembly::SET_LOCAL_V128_S;
|
|
||||||
case WebAssembly::SHL_I32: return WebAssembly::SHL_I32_S;
|
|
||||||
case WebAssembly::SHL_I64: return WebAssembly::SHL_I64_S;
|
|
||||||
case WebAssembly::SHR_S_I32: return WebAssembly::SHR_S_I32_S;
|
|
||||||
case WebAssembly::SHR_S_I64: return WebAssembly::SHR_S_I64_S;
|
|
||||||
case WebAssembly::SHR_U_I32: return WebAssembly::SHR_U_I32_S;
|
|
||||||
case WebAssembly::SHR_U_I64: return WebAssembly::SHR_U_I64_S;
|
|
||||||
case WebAssembly::SQRT_F32: return WebAssembly::SQRT_F32_S;
|
|
||||||
case WebAssembly::SQRT_F64: return WebAssembly::SQRT_F64_S;
|
|
||||||
case WebAssembly::STORE16_I32: return WebAssembly::STORE16_I32_S;
|
|
||||||
case WebAssembly::STORE16_I64: return WebAssembly::STORE16_I64_S;
|
|
||||||
case WebAssembly::STORE32_I64: return WebAssembly::STORE32_I64_S;
|
|
||||||
case WebAssembly::STORE8_I32: return WebAssembly::STORE8_I32_S;
|
|
||||||
case WebAssembly::STORE8_I64: return WebAssembly::STORE8_I64_S;
|
|
||||||
case WebAssembly::STORE_F32: return WebAssembly::STORE_F32_S;
|
|
||||||
case WebAssembly::STORE_F64: return WebAssembly::STORE_F64_S;
|
|
||||||
case WebAssembly::STORE_I32: return WebAssembly::STORE_I32_S;
|
|
||||||
case WebAssembly::STORE_I64: return WebAssembly::STORE_I64_S;
|
|
||||||
case WebAssembly::SUB_F32: return WebAssembly::SUB_F32_S;
|
|
||||||
case WebAssembly::SUB_F32x4: return WebAssembly::SUB_F32x4_S;
|
|
||||||
case WebAssembly::SUB_F64: return WebAssembly::SUB_F64_S;
|
|
||||||
case WebAssembly::SUB_I16x8: return WebAssembly::SUB_I16x8_S;
|
|
||||||
case WebAssembly::SUB_I32: return WebAssembly::SUB_I32_S;
|
|
||||||
case WebAssembly::SUB_I32x4: return WebAssembly::SUB_I32x4_S;
|
|
||||||
case WebAssembly::SUB_I64: return WebAssembly::SUB_I64_S;
|
|
||||||
case WebAssembly::SUB_I8x16: return WebAssembly::SUB_I8x16_S;
|
|
||||||
case WebAssembly::TEE_EXCEPT_REF: return WebAssembly::TEE_EXCEPT_REF_S;
|
|
||||||
case WebAssembly::TEE_F32: return WebAssembly::TEE_F32_S;
|
|
||||||
case WebAssembly::TEE_F64: return WebAssembly::TEE_F64_S;
|
|
||||||
case WebAssembly::TEE_I32: return WebAssembly::TEE_I32_S;
|
|
||||||
case WebAssembly::TEE_I64: return WebAssembly::TEE_I64_S;
|
|
||||||
case WebAssembly::TEE_LOCAL_EXCEPT_REF: return WebAssembly::TEE_LOCAL_EXCEPT_REF_S;
|
|
||||||
case WebAssembly::TEE_LOCAL_F32: return WebAssembly::TEE_LOCAL_F32_S;
|
|
||||||
case WebAssembly::TEE_LOCAL_F64: return WebAssembly::TEE_LOCAL_F64_S;
|
|
||||||
case WebAssembly::TEE_LOCAL_I32: return WebAssembly::TEE_LOCAL_I32_S;
|
|
||||||
case WebAssembly::TEE_LOCAL_I64: return WebAssembly::TEE_LOCAL_I64_S;
|
|
||||||
case WebAssembly::TEE_LOCAL_V128: return WebAssembly::TEE_LOCAL_V128_S;
|
|
||||||
case WebAssembly::TEE_V128: return WebAssembly::TEE_V128_S;
|
|
||||||
case WebAssembly::THROW_I32: return WebAssembly::THROW_I32_S;
|
|
||||||
case WebAssembly::THROW_I64: return WebAssembly::THROW_I64_S;
|
|
||||||
case WebAssembly::TRUNC_F32: return WebAssembly::TRUNC_F32_S;
|
|
||||||
case WebAssembly::TRUNC_F64: return WebAssembly::TRUNC_F64_S;
|
|
||||||
case WebAssembly::TRY: return WebAssembly::TRY_S;
|
|
||||||
case WebAssembly::UNREACHABLE: return WebAssembly::UNREACHABLE_S;
|
|
||||||
case WebAssembly::XOR_I32: return WebAssembly::XOR_I32_S;
|
|
||||||
case WebAssembly::XOR_I64: return WebAssembly::XOR_I64_S;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -57,12 +57,11 @@ let Defs = [ARGUMENTS] in {
|
|||||||
|
|
||||||
// Defines atomic and non-atomic loads, regular and extending.
|
// Defines atomic and non-atomic loads, regular and extending.
|
||||||
multiclass WebAssemblyLoad<WebAssemblyRegClass rc, string Name, int Opcode> {
|
multiclass WebAssemblyLoad<WebAssemblyRegClass rc, string Name, int Opcode> {
|
||||||
let mayLoad = 1 in
|
|
||||||
defm "": I<(outs rc:$dst),
|
defm "": I<(outs rc:$dst),
|
||||||
(ins P2Align:$p2align, offset32_op:$off, I32:$addr),
|
(ins P2Align:$p2align, offset32_op:$off, I32:$addr),
|
||||||
(outs), (ins P2Align:$p2align, offset32_op:$off),
|
(outs), (ins P2Align:$p2align, offset32_op:$off),
|
||||||
[], !strconcat(Name, "\t$dst, ${off}(${addr})${p2align}"),
|
[], !strconcat(Name, "\t$dst, ${off}(${addr})${p2align}"),
|
||||||
!strconcat(Name, "\t${off}${p2align}"), Opcode>;
|
!strconcat(Name, "\t${off}, ${p2align}"), Opcode>;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Basic load.
|
// Basic load.
|
||||||
@ -308,13 +307,12 @@ let Defs = [ARGUMENTS] in {
|
|||||||
|
|
||||||
// Defines atomic and non-atomic stores, regular and truncating
|
// Defines atomic and non-atomic stores, regular and truncating
|
||||||
multiclass WebAssemblyStore<WebAssemblyRegClass rc, string Name, int Opcode> {
|
multiclass WebAssemblyStore<WebAssemblyRegClass rc, string Name, int Opcode> {
|
||||||
let mayStore = 1 in
|
|
||||||
defm "" : I<(outs),
|
defm "" : I<(outs),
|
||||||
(ins P2Align:$p2align, offset32_op:$off, I32:$addr, rc:$val),
|
(ins P2Align:$p2align, offset32_op:$off, I32:$addr, rc:$val),
|
||||||
(outs),
|
(outs),
|
||||||
(ins P2Align:$p2align, offset32_op:$off), [],
|
(ins P2Align:$p2align, offset32_op:$off), [],
|
||||||
!strconcat(Name, "\t${off}(${addr})${p2align}, $val"),
|
!strconcat(Name, "\t${off}(${addr})${p2align}, $val"),
|
||||||
!strconcat(Name, "\t${off}${p2align}"), Opcode>;
|
!strconcat(Name, "\t${off}, ${p2align}"), Opcode>;
|
||||||
}
|
}
|
||||||
// Basic store.
|
// Basic store.
|
||||||
// Note: WebAssembly inverts SelectionDAG's usual operand order.
|
// Note: WebAssembly inverts SelectionDAG's usual operand order.
|
||||||
@ -472,12 +470,12 @@ defm CURRENT_MEMORY_I32 : I<(outs I32:$dst), (ins i32imm:$flags),
|
|||||||
|
|
||||||
// Grow memory.
|
// Grow memory.
|
||||||
defm MEMORY_GROW_I32 : I<(outs I32:$dst), (ins i32imm:$flags, I32:$delta),
|
defm MEMORY_GROW_I32 : I<(outs I32:$dst), (ins i32imm:$flags, I32:$delta),
|
||||||
(outs), (ins i32imm:$flags),
|
(outs), (ins i32imm:$flags, I32:$delta),
|
||||||
[(set I32:$dst,
|
[(set I32:$dst,
|
||||||
(int_wasm_memory_grow (i32 imm:$flags),
|
(int_wasm_memory_grow (i32 imm:$flags),
|
||||||
I32:$delta))],
|
I32:$delta))],
|
||||||
"memory.grow\t$dst, $flags, $delta",
|
"memory.grow\t$dst, $flags, $delta",
|
||||||
"memory.grow\t$flags", 0x3f>,
|
"memory.grow\t$flags, $delta", 0x3f>,
|
||||||
Requires<[HasAddr32]>;
|
Requires<[HasAddr32]>;
|
||||||
defm MEM_GROW_I32 : I<(outs I32:$dst), (ins i32imm:$flags, I32:$delta),
|
defm MEM_GROW_I32 : I<(outs I32:$dst), (ins i32imm:$flags, I32:$delta),
|
||||||
(outs), (ins i32imm:$flags),
|
(outs), (ins i32imm:$flags),
|
||||||
|
@ -317,6 +317,9 @@ void WebAssemblyPassConfig::addPreEmitPass() {
|
|||||||
// converted into a local.
|
// converted into a local.
|
||||||
addPass(createWebAssemblyFixIrreducibleControlFlow());
|
addPass(createWebAssemblyFixIrreducibleControlFlow());
|
||||||
|
|
||||||
|
// Insert explicit get_local and set_local operators.
|
||||||
|
addPass(createWebAssemblyExplicitLocals());
|
||||||
|
|
||||||
// Do various transformations for exception handling
|
// Do various transformations for exception handling
|
||||||
addPass(createWebAssemblyLateEHPrepare());
|
addPass(createWebAssemblyLateEHPrepare());
|
||||||
|
|
||||||
@ -334,9 +337,6 @@ void WebAssemblyPassConfig::addPreEmitPass() {
|
|||||||
if (getOptLevel() != CodeGenOpt::None)
|
if (getOptLevel() != CodeGenOpt::None)
|
||||||
addPass(createWebAssemblyPeephole());
|
addPass(createWebAssemblyPeephole());
|
||||||
|
|
||||||
// Insert explicit get_local and set_local operators.
|
|
||||||
addPass(createWebAssemblyExplicitLocals());
|
|
||||||
|
|
||||||
// Create a mapping from LLVM CodeGen virtual registers to wasm registers.
|
// Create a mapping from LLVM CodeGen virtual registers to wasm registers.
|
||||||
addPass(createWebAssemblyRegNumbering());
|
addPass(createWebAssemblyRegNumbering());
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
|
||||||
|
|
||||||
; Test folding constant offsets and symbols into load and store addresses under
|
; Test folding constant offsets and symbols into load and store addresses under
|
||||||
; a variety of circumstances.
|
; a variety of circumstances.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: not llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode
|
; RUN: not llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt
|
||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -mattr=+atomics,+sign-ext | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -mattr=+atomics,+sign-ext | FileCheck %s
|
||||||
|
|
||||||
; Test atomic RMW (read-modify-write) instructions are assembled properly.
|
; Test atomic RMW (read-modify-write) instructions are assembled properly.
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -verify-machineinstrs | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -verify-machineinstrs | FileCheck %s
|
||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -verify-machineinstrs -fast-isel | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -verify-machineinstrs -fast-isel | FileCheck %s
|
||||||
|
|
||||||
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
||||||
target triple = "wasm32-unknown-unknown"
|
target triple = "wasm32-unknown-unknown"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode -wasm-temporary-workarounds=false | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-temporary-workarounds=false | FileCheck %s
|
||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode -fast-isel -fast-isel-abort=1 -wasm-temporary-workarounds=false | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -fast-isel -fast-isel-abort=1 -wasm-temporary-workarounds=false | FileCheck %s
|
||||||
|
|
||||||
; Test that basic call operations assemble as expected.
|
; Test that basic call operations assemble as expected.
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -disable-block-placement -verify-machineinstrs -fast-isel=false -machine-sink-split-probability-threshold=0 -cgp-freq-ratio-to-skip-merge=1000 | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -disable-block-placement -verify-machineinstrs -fast-isel=false -machine-sink-split-probability-threshold=0 -cgp-freq-ratio-to-skip-merge=1000 | FileCheck %s
|
||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -tail-dup-placement=0 -verify-machineinstrs -fast-isel=false -machine-sink-split-probability-threshold=0 -cgp-freq-ratio-to-skip-merge=1000 | FileCheck -check-prefix=OPT %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -tail-dup-placement=0 -verify-machineinstrs -fast-isel=false -machine-sink-split-probability-threshold=0 -cgp-freq-ratio-to-skip-merge=1000 | FileCheck -check-prefix=OPT %s
|
||||||
|
|
||||||
; Test the CFG stackifier pass.
|
; Test the CFG stackifier pass.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: opt -S -lowertypetests < %s | llc -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode | FileCheck %s
|
; RUN: opt -S -lowertypetests < %s | llc -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
|
||||||
|
|
||||||
; Tests that we correctly assign indexes for control flow integrity.
|
; Tests that we correctly assign indexes for control flow integrity.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
|
||||||
|
|
||||||
; Test that basic 32-bit floating-point comparison operations assemble as
|
; Test that basic 32-bit floating-point comparison operations assemble as
|
||||||
; expected.
|
; expected.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
|
||||||
|
|
||||||
; Test that basic 64-bit floating-point comparison operations assemble as
|
; Test that basic 64-bit floating-point comparison operations assemble as
|
||||||
; expected.
|
; expected.
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
|
||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode -fast-isel -fast-isel-abort=1 | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -fast-isel -fast-isel-abort=1 | FileCheck %s
|
||||||
|
|
||||||
; Test that basic 32-bit integer comparison operations assemble as expected.
|
; Test that basic 32-bit integer comparison operations assemble as expected.
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
|
||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode -fast-isel -fast-isel-abort=1 | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -fast-isel -fast-isel-abort=1 | FileCheck %s
|
||||||
|
|
||||||
; Test that basic 64-bit integer comparison operations assemble as expected.
|
; Test that basic 64-bit integer comparison operations assemble as expected.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -mattr=-nontrapping-fptoint | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -mattr=-nontrapping-fptoint | FileCheck %s
|
||||||
|
|
||||||
; Test that basic conversion operations assemble as expected using
|
; Test that basic conversion operations assemble as expected using
|
||||||
; the trapping opcodes and explicit code to suppress the trapping.
|
; the trapping opcodes and explicit code to suppress the trapping.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -mattr=+nontrapping-fptoint | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -mattr=+nontrapping-fptoint | FileCheck %s
|
||||||
|
|
||||||
; Test that basic conversion operations assemble as expected.
|
; Test that basic conversion operations assemble as expected.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -wasm-explicit-locals-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false | FileCheck %s
|
||||||
|
|
||||||
; DAGCombiner oddly folds casts into the rhs of copysign. Test that they get
|
; DAGCombiner oddly folds casts into the rhs of copysign. Test that they get
|
||||||
; unfolded.
|
; unfolded.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -wasm-explicit-locals-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false | FileCheck %s
|
||||||
|
|
||||||
; Test that integer div and rem by constant are optimized appropriately.
|
; Test that integer div and rem by constant are optimized appropriately.
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: not llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode -exception-model=wasm
|
; RUN: not llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -exception-model=wasm
|
||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode -exception-model=wasm -mattr=+exception-handling | FileCheck -allow-deprecated-dag-overlap %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -exception-model=wasm -mattr=+exception-handling | FileCheck -allow-deprecated-dag-overlap %s
|
||||||
|
|
||||||
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
||||||
target triple = "wasm32-unknown-unknown"
|
target triple = "wasm32-unknown-unknown"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# RUN: llc -mtriple=wasm32-unknown-unknown -run-pass wasm-explicit-locals -wasm-explicit-locals-codegen-test-mode %s -o - | FileCheck %s
|
# RUN: llc -mtriple=wasm32-unknown-unknown -run-pass wasm-explicit-locals %s -o - | FileCheck %s
|
||||||
|
|
||||||
# When a drop instruction is inserted to drop a dead register operand, the
|
# When a drop instruction is inserted to drop a dead register operand, the
|
||||||
# original operand should be marked not dead anymore because it is now used by
|
# original operand should be marked not dead anymore because it is now used by
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
|
||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode -fast-isel | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -fast-isel | FileCheck %s
|
||||||
|
|
||||||
; Test that f16 is expanded.
|
; Test that f16 is expanded.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
|
||||||
|
|
||||||
; Test that basic 32-bit floating-point operations assemble as expected.
|
; Test that basic 32-bit floating-point operations assemble as expected.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
|
||||||
|
|
||||||
; Test that basic 64-bit floating-point operations assemble as expected.
|
; Test that basic 64-bit floating-point operations assemble as expected.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -fast-isel -asm-verbose=false -wasm-explicit-locals-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -fast-isel -asm-verbose=false | FileCheck %s
|
||||||
|
|
||||||
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
||||||
target triple = "wasm32-unknown-unknown"
|
target triple = "wasm32-unknown-unknown"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -O0 -wasm-explicit-locals-codegen-test-mode
|
; RUN: llc < %s -O0
|
||||||
; PR36564
|
; PR36564
|
||||||
; PR37546
|
; PR37546
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -O0 -wasm-explicit-locals-codegen-test-mode
|
; RUN: llc < %s -O0
|
||||||
; PR36564
|
; PR36564
|
||||||
; PR37546
|
; PR37546
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode -verify-machineinstrs | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -verify-machineinstrs | FileCheck %s
|
||||||
; RUN: llc < %s -asm-verbose=false -wasm-explicit-locals-codegen-test-mode -fast-isel -verify-machineinstrs | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -fast-isel -verify-machineinstrs | FileCheck %s
|
||||||
|
|
||||||
; Test that FastISel does not generate instructions with NoReg
|
; Test that FastISel does not generate instructions with NoReg
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false \
|
; RUN: llc < %s -asm-verbose=false \
|
||||||
; RUN: -fast-isel -fast-isel-abort=1 -verify-machineinstrs \
|
; RUN: -fast-isel -fast-isel-abort=1 -verify-machineinstrs \
|
||||||
; RUN: -wasm-register-codegen-test-mode \
|
; RUN: -disable-wasm-explicit-locals \
|
||||||
; RUN: | FileCheck %s
|
; RUN: | FileCheck %s
|
||||||
|
|
||||||
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
|
||||||
|
|
||||||
; Test that the frem instruction works.
|
; Test that the frem instruction works.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
|
||||||
|
|
||||||
; Test that basic functions assemble as expected.
|
; Test that basic functions assemble as expected.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -wasm-temporary-workarounds=false -wasm-explicit-locals-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -wasm-temporary-workarounds=false | FileCheck %s
|
||||||
|
|
||||||
; Test that function pointer casts casting away varargs are replaced with
|
; Test that function pointer casts casting away varargs are replaced with
|
||||||
; wrappers.
|
; wrappers.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -wasm-register-codegen-test-mode -enable-emscripten-cxx-exceptions -wasm-temporary-workarounds=false | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-explicit-locals -enable-emscripten-cxx-exceptions -wasm-temporary-workarounds=false | FileCheck %s
|
||||||
|
|
||||||
; Test that function pointer casts are replaced with wrappers.
|
; Test that function pointer casts are replaced with wrappers.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
|
||||||
|
|
||||||
; Test that globals assemble as expected.
|
; Test that globals assemble as expected.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
|
||||||
|
|
||||||
; Test that basic 128-bit integer operations assemble as expected.
|
; Test that basic 128-bit integer operations assemble as expected.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -mattr=+atomics -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -mattr=+atomics -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
|
||||||
|
|
||||||
; Test loads and stores with custom alignment values.
|
; Test loads and stores with custom alignment values.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
|
||||||
|
|
||||||
; Test that basic 32-bit integer operations assemble as expected.
|
; Test that basic 32-bit integer operations assemble as expected.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -mattr=+atomics -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -mattr=+atomics -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
|
||||||
|
|
||||||
; Test loads and stores with custom alignment values.
|
; Test loads and stores with custom alignment values.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
|
||||||
|
|
||||||
; Test that basic 64-bit integer operations assemble as expected.
|
; Test that basic 64-bit integer operations assemble as expected.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -wasm-explicit-locals-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false | FileCheck %s
|
||||||
|
|
||||||
; Test llvm.ident.
|
; Test llvm.ident.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
|
||||||
|
|
||||||
; Test that basic immediates assemble as expected.
|
; Test that basic immediates assemble as expected.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc -o - %s -asm-verbose=false -wasm-explicit-locals-codegen-test-mode | FileCheck %s
|
; RUN: llc -o - %s -asm-verbose=false | FileCheck %s
|
||||||
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
||||||
target triple = "wasm32-unknown-unknown"
|
target triple = "wasm32-unknown-unknown"
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -wasm-explicit-locals-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false | FileCheck %s
|
||||||
|
|
||||||
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
||||||
target triple = "wasm32-unknown-unknown"
|
target triple = "wasm32-unknown-unknown"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode -verify-machineinstrs | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -verify-machineinstrs | FileCheck %s
|
||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode -verify-machineinstrs -fast-isel | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -verify-machineinstrs -fast-isel | FileCheck %s
|
||||||
|
|
||||||
; ModuleID = 'test/dot_s/indirect-import.c'
|
; ModuleID = 'test/dot_s/indirect-import.c'
|
||||||
source_filename = "test/dot_s/indirect-import.c"
|
source_filename = "test/dot_s/indirect-import.c"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: not llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -no-integrated-as
|
; RUN: not llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -no-integrated-as
|
||||||
|
|
||||||
; Test basic inline assembly "m" operands, which are unsupported. Pass
|
; Test basic inline assembly "m" operands, which are unsupported. Pass
|
||||||
; -no-integrated-as since these aren't actually valid assembly syntax.
|
; -no-integrated-as since these aren't actually valid assembly syntax.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode -no-integrated-as | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -no-integrated-as | FileCheck %s
|
||||||
|
|
||||||
; Test basic inline assembly. Pass -no-integrated-as since these aren't
|
; Test basic inline assembly. Pass -no-integrated-as since these aren't
|
||||||
; actually valid assembly syntax.
|
; actually valid assembly syntax.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-block-placement -wasm-register-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-block-placement -disable-wasm-explicit-locals | FileCheck %s
|
||||||
|
|
||||||
; Test irreducible CFG handling.
|
; Test irreducible CFG handling.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
|
||||||
|
|
||||||
; Test various types and operators that need to be legalized.
|
; Test various types and operators that need to be legalized.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
|
||||||
|
|
||||||
; Test a subset of compiler-rt/libm libcalls expected to be emitted by the wasm backend
|
; Test a subset of compiler-rt/libm libcalls expected to be emitted by the wasm backend
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -mattr=+atomics,+sign-ext -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -mattr=+atomics,+sign-ext -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
|
||||||
|
|
||||||
; Test that extending loads are assembled properly.
|
; Test that extending loads are assembled properly.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
|
||||||
|
|
||||||
; Test that extending loads are assembled properly.
|
; Test that extending loads are assembled properly.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
|
||||||
|
|
||||||
; Test that i1 extending loads and truncating stores are assembled properly.
|
; Test that i1 extending loads and truncating stores are assembled properly.
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
|
||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode -fast-isel -fast-isel-abort=1 | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -fast-isel -fast-isel-abort=1 | FileCheck %s
|
||||||
|
|
||||||
; Test that basic loads are assembled properly.
|
; Test that basic loads are assembled properly.
|
||||||
|
|
||||||
|
@ -39,9 +39,9 @@ entry:
|
|||||||
%arraydecay1 = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %buf, i32 0, i32 0
|
%arraydecay1 = getelementptr inbounds [1 x %struct.__jmp_buf_tag], [1 x %struct.__jmp_buf_tag]* %buf, i32 0, i32 0
|
||||||
call void @longjmp(%struct.__jmp_buf_tag* %arraydecay1, i32 1) #1
|
call void @longjmp(%struct.__jmp_buf_tag* %arraydecay1, i32 1) #1
|
||||||
unreachable
|
unreachable
|
||||||
; SJLJ: i32.call saveSetjmp@FUNCTION
|
; SJLJ: i32.call ${{[a-zA-Z0-9]+}}=, saveSetjmp@FUNCTION
|
||||||
; SJLJ: i32.call testSetjmp@FUNCTION
|
; SJLJ: i32.call ${{[a-zA-Z0-9]+}}=, testSetjmp@FUNCTION
|
||||||
; NONE: i32.call setjmp@FUNCTION
|
; NONE: i32.call ${{[a-zA-Z0-9]+}}=, setjmp@FUNCTION
|
||||||
; NONE: call longjmp@FUNCTION
|
; NONE: call longjmp@FUNCTION
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -wasm-explicit-locals-codegen-test-mode | FileCheck --check-prefix=CHECK --check-prefix=FINI --check-prefix=NULL %s
|
; RUN: llc < %s -asm-verbose=false | FileCheck --check-prefix=CHECK --check-prefix=FINI --check-prefix=NULL %s
|
||||||
|
|
||||||
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
||||||
target triple = "wasm32-unknown-unknown"
|
target triple = "wasm32-unknown-unknown"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -tail-dup-placement=0 | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -tail-dup-placement=0 | FileCheck %s
|
||||||
|
|
||||||
; Test memcpy, memmove, and memset intrinsics.
|
; Test memcpy, memmove, and memset intrinsics.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
|
||||||
|
|
||||||
; Test that basic memory operations assemble as expected with 32-bit addresses.
|
; Test that basic memory operations assemble as expected with 32-bit addresses.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc -asm-verbose=false < %s -wasm-explicit-locals-codegen-test-mode | FileCheck %s
|
; RUN: llc -asm-verbose=false < %s | FileCheck %s
|
||||||
|
|
||||||
; Test that 128-bit smul.with.overflow assembles as expected.
|
; Test that 128-bit smul.with.overflow assembles as expected.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -verify-machineinstrs -disable-wasm-fallthrough-return-opt | FileCheck %s
|
||||||
|
|
||||||
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
||||||
target triple = "wasm32-unknown-unknown"
|
target triple = "wasm32-unknown-unknown"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: not llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt
|
; RUN: not llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt
|
||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -mattr=+atomics,+sign-ext | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -mattr=+atomics,+sign-ext | FileCheck %s
|
||||||
|
|
||||||
; Test that atomic loads are assembled properly.
|
; Test that atomic loads are assembled properly.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -wasm-register-codegen-test-mode -fast-isel -fast-isel-abort=1 | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-explicit-locals -fast-isel -fast-isel-abort=1 | FileCheck %s
|
||||||
|
|
||||||
; TODO: Merge this with offset.ll when fast-isel matches better.
|
; TODO: Merge this with offset.ll when fast-isel matches better.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -wasm-explicit-locals-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false | FileCheck %s
|
||||||
|
|
||||||
; Test that constant offsets can be folded into global addresses.
|
; Test that constant offsets can be folded into global addresses.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -wasm-register-codegen-test-mode -disable-wasm-fallthrough-return-opt | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-explicit-locals -disable-wasm-fallthrough-return-opt | FileCheck %s
|
||||||
|
|
||||||
; Test constant load and store address offsets.
|
; Test constant load and store address offsets.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -verify-machineinstrs | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -verify-machineinstrs | FileCheck %s
|
||||||
|
|
||||||
; Test that phis are lowered.
|
; Test that phis are lowered.
|
||||||
|
|
||||||
|
@ -1,11 +1,7 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -verify-machineinstrs | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -verify-machineinstrs | FileCheck %s
|
||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -verify-machineinstrs | FileCheck %s --check-prefix=NOREGS
|
|
||||||
|
|
||||||
; Test the register stackifier pass.
|
; Test the register stackifier pass.
|
||||||
|
|
||||||
; We have two sets of tests, one with registers and implicit locals, and
|
|
||||||
; a stack / explicit locals based version (NOREGS).
|
|
||||||
|
|
||||||
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
||||||
target triple = "wasm32-unknown-unknown"
|
target triple = "wasm32-unknown-unknown"
|
||||||
|
|
||||||
@ -13,8 +9,6 @@ target triple = "wasm32-unknown-unknown"
|
|||||||
|
|
||||||
; CHECK-LABEL: no0:
|
; CHECK-LABEL: no0:
|
||||||
; CHECK: return $1{{$}}
|
; CHECK: return $1{{$}}
|
||||||
; NOREGS-LABEL: no0:
|
|
||||||
; NOREGS: return{{$}}
|
|
||||||
define i32 @no0(i32* %p, i32* %q) {
|
define i32 @no0(i32* %p, i32* %q) {
|
||||||
%t = load i32, i32* %q
|
%t = load i32, i32* %q
|
||||||
store i32 0, i32* %p
|
store i32 0, i32* %p
|
||||||
@ -25,8 +19,6 @@ define i32 @no0(i32* %p, i32* %q) {
|
|||||||
|
|
||||||
; CHECK-LABEL: no1:
|
; CHECK-LABEL: no1:
|
||||||
; CHECK: return $1{{$}}
|
; CHECK: return $1{{$}}
|
||||||
; NOREGS-LABEL: no1:
|
|
||||||
; NOREGS: return{{$}}
|
|
||||||
define i32 @no1(i32* %p, i32* dereferenceable(4) %q) {
|
define i32 @no1(i32* %p, i32* dereferenceable(4) %q) {
|
||||||
%t = load volatile i32, i32* %q, !invariant.load !0
|
%t = load volatile i32, i32* %q, !invariant.load !0
|
||||||
store volatile i32 0, i32* %p
|
store volatile i32 0, i32* %p
|
||||||
@ -37,8 +29,6 @@ define i32 @no1(i32* %p, i32* dereferenceable(4) %q) {
|
|||||||
|
|
||||||
; CHECK-LABEL: yes0:
|
; CHECK-LABEL: yes0:
|
||||||
; CHECK: return $pop{{[0-9]+}}{{$}}
|
; CHECK: return $pop{{[0-9]+}}{{$}}
|
||||||
; NOREGS-LABEL: yes0:
|
|
||||||
; NOREGS: return{{$}}
|
|
||||||
define i32 @yes0(i32* %p, i32* dereferenceable(4) %q) {
|
define i32 @yes0(i32* %p, i32* dereferenceable(4) %q) {
|
||||||
%t = load i32, i32* %q, !invariant.load !0
|
%t = load i32, i32* %q, !invariant.load !0
|
||||||
store i32 0, i32* %p
|
store i32 0, i32* %p
|
||||||
@ -49,8 +39,6 @@ define i32 @yes0(i32* %p, i32* dereferenceable(4) %q) {
|
|||||||
|
|
||||||
; CHECK-LABEL: yes1:
|
; CHECK-LABEL: yes1:
|
||||||
; CHECK: return $pop0{{$}}
|
; CHECK: return $pop0{{$}}
|
||||||
; NOREGS-LABEL: yes1:
|
|
||||||
; NOREGS: return{{$}}
|
|
||||||
define i32 @yes1(i32* %q) {
|
define i32 @yes1(i32* %q) {
|
||||||
%t = load volatile i32, i32* %q
|
%t = load volatile i32, i32* %q
|
||||||
ret i32 %t
|
ret i32 %t
|
||||||
@ -60,8 +48,6 @@ define i32 @yes1(i32* %q) {
|
|||||||
|
|
||||||
; CHECK-LABEL: sink_trap:
|
; CHECK-LABEL: sink_trap:
|
||||||
; CHECK: return $pop{{[0-9]+}}{{$}}
|
; CHECK: return $pop{{[0-9]+}}{{$}}
|
||||||
; NOREGS-LABEL: sink_trap:
|
|
||||||
; NOREGS: return{{$}}
|
|
||||||
define i32 @sink_trap(i32 %x, i32 %y, i32* %p) {
|
define i32 @sink_trap(i32 %x, i32 %y, i32* %p) {
|
||||||
%t = sdiv i32 %x, %y
|
%t = sdiv i32 %x, %y
|
||||||
store volatile i32 0, i32* %p
|
store volatile i32 0, i32* %p
|
||||||
@ -72,8 +58,6 @@ define i32 @sink_trap(i32 %x, i32 %y, i32* %p) {
|
|||||||
|
|
||||||
; CHECK-LABEL: sink_readnone_call:
|
; CHECK-LABEL: sink_readnone_call:
|
||||||
; CHECK: return $pop0{{$}}
|
; CHECK: return $pop0{{$}}
|
||||||
; NOREGS-LABEL: sink_readnone_call:
|
|
||||||
; NOREGS: return{{$}}
|
|
||||||
declare i32 @readnone_callee() readnone nounwind
|
declare i32 @readnone_callee() readnone nounwind
|
||||||
define i32 @sink_readnone_call(i32 %x, i32 %y, i32* %p) {
|
define i32 @sink_readnone_call(i32 %x, i32 %y, i32* %p) {
|
||||||
%t = call i32 @readnone_callee()
|
%t = call i32 @readnone_callee()
|
||||||
@ -85,8 +69,6 @@ define i32 @sink_readnone_call(i32 %x, i32 %y, i32* %p) {
|
|||||||
|
|
||||||
; CHECK-LABEL: no_sink_readonly_call:
|
; CHECK-LABEL: no_sink_readonly_call:
|
||||||
; CHECK: return ${{[0-9]+}}{{$}}
|
; CHECK: return ${{[0-9]+}}{{$}}
|
||||||
; NOREGS-LABEL: no_sink_readonly_call:
|
|
||||||
; NOREGS: return{{$}}
|
|
||||||
declare i32 @readonly_callee() readonly nounwind
|
declare i32 @readonly_callee() readonly nounwind
|
||||||
define i32 @no_sink_readonly_call(i32 %x, i32 %y, i32* %p) {
|
define i32 @no_sink_readonly_call(i32 %x, i32 %y, i32* %p) {
|
||||||
%t = call i32 @readonly_callee()
|
%t = call i32 @readonly_callee()
|
||||||
@ -123,34 +105,6 @@ define i32 @no_sink_readonly_call(i32 %x, i32 %y, i32* %p) {
|
|||||||
; CHECK-NEXT: end_block{{$}}
|
; CHECK-NEXT: end_block{{$}}
|
||||||
; CHECK-NEXT: i32.const $push14=, 1{{$}}
|
; CHECK-NEXT: i32.const $push14=, 1{{$}}
|
||||||
; CHECK-NEXT: return $pop14{{$}}
|
; CHECK-NEXT: return $pop14{{$}}
|
||||||
; NOREGS-LABEL: stack_uses:
|
|
||||||
; NOREGS: .param i32, i32, i32, i32{{$}}
|
|
||||||
; NOREGS-NEXT: .result i32{{$}}
|
|
||||||
; NOREGS-NEXT: block {{$}}
|
|
||||||
; NOREGS-NEXT: get_local 0{{$}}
|
|
||||||
; NOREGS-NEXT: i32.const 1{{$}}
|
|
||||||
; NOREGS-NEXT: i32.lt_s
|
|
||||||
; NOREGS-NEXT: get_local 1{{$}}
|
|
||||||
; NOREGS-NEXT: i32.const 2{{$}}
|
|
||||||
; NOREGS-NEXT: i32.lt_s
|
|
||||||
; NOREGS-NEXT: i32.xor {{$}}
|
|
||||||
; NOREGS-NEXT: get_local 2{{$}}
|
|
||||||
; NOREGS-NEXT: i32.const 1{{$}}
|
|
||||||
; NOREGS-NEXT: i32.lt_s
|
|
||||||
; NOREGS-NEXT: get_local 3{{$}}
|
|
||||||
; NOREGS-NEXT: i32.const 2{{$}}
|
|
||||||
; NOREGS-NEXT: i32.lt_s
|
|
||||||
; NOREGS-NEXT: i32.xor {{$}}
|
|
||||||
; NOREGS-NEXT: i32.xor {{$}}
|
|
||||||
; NOREGS-NEXT: i32.const 1{{$}}
|
|
||||||
; NOREGS-NEXT: i32.ne {{$}}
|
|
||||||
; NOREGS-NEXT: br_if 0{{$}}
|
|
||||||
; NOREGS-NEXT: i32.const 0{{$}}
|
|
||||||
; NOREGS-NEXT: return{{$}}
|
|
||||||
; NOREGS-NEXT: .LBB7_2:
|
|
||||||
; NOREGS-NEXT: end_block{{$}}
|
|
||||||
; NOREGS-NEXT: i32.const 1{{$}}
|
|
||||||
; NOREGS-NEXT: return{{$}}
|
|
||||||
define i32 @stack_uses(i32 %x, i32 %y, i32 %z, i32 %w) {
|
define i32 @stack_uses(i32 %x, i32 %y, i32 %z, i32 %w) {
|
||||||
entry:
|
entry:
|
||||||
%c = icmp sle i32 %x, 0
|
%c = icmp sle i32 %x, 0
|
||||||
@ -183,26 +137,6 @@ false:
|
|||||||
; CHECK-NEXT: .LBB8_3:
|
; CHECK-NEXT: .LBB8_3:
|
||||||
; CHECK-NEXT: end_block{{$}}
|
; CHECK-NEXT: end_block{{$}}
|
||||||
; CHECK-NEXT: return{{$}}
|
; CHECK-NEXT: return{{$}}
|
||||||
; NOREGS-LABEL: multiple_uses:
|
|
||||||
; NOREGS: .param i32, i32, i32{{$}}
|
|
||||||
; NOREGS: .local i32{{$}}
|
|
||||||
; NOREGS-NEXT: block {{$}}
|
|
||||||
; NOREGS-NEXT: get_local 2{{$}}
|
|
||||||
; NOREGS-NEXT: i32.load 0{{$}}
|
|
||||||
; NOREGS-NEXT: tee_local 3{{$}}
|
|
||||||
; NOREGS-NEXT: get_local 1{{$}}
|
|
||||||
; NOREGS-NEXT: i32.ge_u
|
|
||||||
; NOREGS-NEXT: br_if 0{{$}}
|
|
||||||
; NOREGS-NEXT: get_local 3{{$}}
|
|
||||||
; NOREGS-NEXT: get_local 0{{$}}
|
|
||||||
; NOREGS-NEXT: i32.lt_u
|
|
||||||
; NOREGS-NEXT: br_if 0{{$}}
|
|
||||||
; NOREGS-NEXT: get_local 2{{$}}
|
|
||||||
; NOREGS-NEXT: get_local 3{{$}}
|
|
||||||
; NOREGS-NEXT: i32.store 0{{$}}
|
|
||||||
; NOREGS-NEXT: .LBB8_3:
|
|
||||||
; NOREGS-NEXT: end_block{{$}}
|
|
||||||
; NOREGS-NEXT: return{{$}}
|
|
||||||
define void @multiple_uses(i32* %arg0, i32* %arg1, i32* %arg2) nounwind {
|
define void @multiple_uses(i32* %arg0, i32* %arg1, i32* %arg2) nounwind {
|
||||||
bb:
|
bb:
|
||||||
br label %loop
|
br label %loop
|
||||||
@ -233,11 +167,6 @@ return:
|
|||||||
; CHECK-NEXT: call
|
; CHECK-NEXT: call
|
||||||
; CHECK: store
|
; CHECK: store
|
||||||
; CHECK-NEXT: call
|
; CHECK-NEXT: call
|
||||||
; NOREGS: side_effects:
|
|
||||||
; NOREGS: store
|
|
||||||
; NOREGS-NEXT: call
|
|
||||||
; NOREGS: store
|
|
||||||
; NOREGS-NEXT: call
|
|
||||||
declare void @evoke_side_effects()
|
declare void @evoke_side_effects()
|
||||||
define hidden void @stackify_store_across_side_effects(double* nocapture %d) {
|
define hidden void @stackify_store_across_side_effects(double* nocapture %d) {
|
||||||
entry:
|
entry:
|
||||||
@ -271,41 +200,6 @@ entry:
|
|||||||
; CHECK-NEXT: i32.div_s $push[[L13:[0-9]+]]=, $pop[[L9]], $pop[[L12]]{{$}}
|
; CHECK-NEXT: i32.div_s $push[[L13:[0-9]+]]=, $pop[[L9]], $pop[[L12]]{{$}}
|
||||||
; CHECK-NEXT: i32.div_s $push[[L14:[0-9]+]]=, $pop[[L6]], $pop[[L13]]{{$}}
|
; CHECK-NEXT: i32.div_s $push[[L14:[0-9]+]]=, $pop[[L6]], $pop[[L13]]{{$}}
|
||||||
; CHECK-NEXT: return $pop[[L14]]{{$}}
|
; CHECK-NEXT: return $pop[[L14]]{{$}}
|
||||||
; NOREGS-LABEL: div_tree:
|
|
||||||
; NOREGS: .param i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32{{$}}
|
|
||||||
; NOREGS-NEXT: .result i32{{$}}
|
|
||||||
; NOREGS-NEXT: get_local 0{{$}}
|
|
||||||
; NOREGS-NEXT: get_local 1{{$}}
|
|
||||||
; NOREGS-NEXT: i32.div_s{{$}}
|
|
||||||
; NOREGS-NEXT: get_local 2{{$}}
|
|
||||||
; NOREGS-NEXT: get_local 3{{$}}
|
|
||||||
; NOREGS-NEXT: i32.div_s{{$}}
|
|
||||||
; NOREGS-NEXT: i32.div_s{{$}}
|
|
||||||
; NOREGS-NEXT: get_local 4{{$}}
|
|
||||||
; NOREGS-NEXT: get_local 5{{$}}
|
|
||||||
; NOREGS-NEXT: i32.div_s{{$}}
|
|
||||||
; NOREGS-NEXT: get_local 6{{$}}
|
|
||||||
; NOREGS-NEXT: get_local 7{{$}}
|
|
||||||
; NOREGS-NEXT: i32.div_s{{$}}
|
|
||||||
; NOREGS-NEXT: i32.div_s{{$}}
|
|
||||||
; NOREGS-NEXT: i32.div_s{{$}}
|
|
||||||
; NOREGS-NEXT: get_local 8{{$}}
|
|
||||||
; NOREGS-NEXT: get_local 9{{$}}
|
|
||||||
; NOREGS-NEXT: i32.div_s{{$}}
|
|
||||||
; NOREGS-NEXT: get_local 10{{$}}
|
|
||||||
; NOREGS-NEXT: get_local 11{{$}}
|
|
||||||
; NOREGS-NEXT: i32.div_s{{$}}
|
|
||||||
; NOREGS-NEXT: i32.div_s{{$}}
|
|
||||||
; NOREGS-NEXT: get_local 12{{$}}
|
|
||||||
; NOREGS-NEXT: get_local 13{{$}}
|
|
||||||
; NOREGS-NEXT: i32.div_s{{$}}
|
|
||||||
; NOREGS-NEXT: get_local 14{{$}}
|
|
||||||
; NOREGS-NEXT: get_local 15{{$}}
|
|
||||||
; NOREGS-NEXT: i32.div_s{{$}}
|
|
||||||
; NOREGS-NEXT: i32.div_s{{$}}
|
|
||||||
; NOREGS-NEXT: i32.div_s{{$}}
|
|
||||||
; NOREGS-NEXT: i32.div_s{{$}}
|
|
||||||
; NOREGS-NEXT: return{{$}}
|
|
||||||
define i32 @div_tree(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i32 %i, i32 %j, i32 %k, i32 %l, i32 %m, i32 %n, i32 %o, i32 %p) {
|
define i32 @div_tree(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e, i32 %f, i32 %g, i32 %h, i32 %i, i32 %j, i32 %k, i32 %l, i32 %m, i32 %n, i32 %o, i32 %p) {
|
||||||
entry:
|
entry:
|
||||||
%div = sdiv i32 %a, %b
|
%div = sdiv i32 %a, %b
|
||||||
@ -335,16 +229,6 @@ entry:
|
|||||||
; CHECK-NEXT: call use_a@FUNCTION, $pop[[NUM1]]{{$}}
|
; CHECK-NEXT: call use_a@FUNCTION, $pop[[NUM1]]{{$}}
|
||||||
; CHECK-NEXT: call use_b@FUNCTION, $[[NUM2]]{{$}}
|
; CHECK-NEXT: call use_b@FUNCTION, $[[NUM2]]{{$}}
|
||||||
; CHECK-NEXT: return{{$}}
|
; CHECK-NEXT: return{{$}}
|
||||||
; NOREGS-LABEL: simple_multiple_use:
|
|
||||||
; NOREGS: .param i32, i32{{$}}
|
|
||||||
; NOREGS-NEXT: get_local 1{{$}}
|
|
||||||
; NOREGS-NEXT: get_local 0{{$}}
|
|
||||||
; NOREGS-NEXT: i32.mul
|
|
||||||
; NOREGS-NEXT: tee_local 1{{$}}
|
|
||||||
; NOREGS-NEXT: call use_a@FUNCTION{{$}}
|
|
||||||
; NOREGS-NEXT: get_local 1{{$}}
|
|
||||||
; NOREGS-NEXT: call use_b@FUNCTION{{$}}
|
|
||||||
; NOREGS-NEXT: return{{$}}
|
|
||||||
declare void @use_a(i32)
|
declare void @use_a(i32)
|
||||||
declare void @use_b(i32)
|
declare void @use_b(i32)
|
||||||
define void @simple_multiple_use(i32 %x, i32 %y) {
|
define void @simple_multiple_use(i32 %x, i32 %y) {
|
||||||
@ -362,15 +246,6 @@ define void @simple_multiple_use(i32 %x, i32 %y) {
|
|||||||
; CHECK-NEXT: tee_local $push[[NUM1:[0-9]+]]=, $[[NUM2:[0-9]+]]=, $pop[[NUM0]]{{$}}
|
; CHECK-NEXT: tee_local $push[[NUM1:[0-9]+]]=, $[[NUM2:[0-9]+]]=, $pop[[NUM0]]{{$}}
|
||||||
; CHECK-NEXT: call use_2@FUNCTION, $pop[[NUM1]], $[[NUM2]]{{$}}
|
; CHECK-NEXT: call use_2@FUNCTION, $pop[[NUM1]], $[[NUM2]]{{$}}
|
||||||
; CHECK-NEXT: return{{$}}
|
; CHECK-NEXT: return{{$}}
|
||||||
; NOREGS-LABEL: multiple_uses_in_same_insn:
|
|
||||||
; NOREGS: .param i32, i32{{$}}
|
|
||||||
; NOREGS-NEXT: get_local 1{{$}}
|
|
||||||
; NOREGS-NEXT: get_local 0{{$}}
|
|
||||||
; NOREGS-NEXT: i32.mul
|
|
||||||
; NOREGS-NEXT: tee_local 1{{$}}
|
|
||||||
; NOREGS-NEXT: get_local 1{{$}}
|
|
||||||
; NOREGS-NEXT: call use_2@FUNCTION{{$}}
|
|
||||||
; NOREGS-NEXT: return{{$}}
|
|
||||||
declare void @use_2(i32, i32)
|
declare void @use_2(i32, i32)
|
||||||
define void @multiple_uses_in_same_insn(i32 %x, i32 %y) {
|
define void @multiple_uses_in_same_insn(i32 %x, i32 %y) {
|
||||||
%mul = mul i32 %y, %x
|
%mul = mul i32 %y, %x
|
||||||
@ -389,15 +264,6 @@ define void @multiple_uses_in_same_insn(i32 %x, i32 %y) {
|
|||||||
; CHECK-NEXT: i32.call $push3=, blue@FUNCTION{{$}}
|
; CHECK-NEXT: i32.call $push3=, blue@FUNCTION{{$}}
|
||||||
; CHECK-NEXT: i32.add $push4=, $pop2, $pop3{{$}}
|
; CHECK-NEXT: i32.add $push4=, $pop2, $pop3{{$}}
|
||||||
; CHECK-NEXT: return $pop4{{$}}
|
; CHECK-NEXT: return $pop4{{$}}
|
||||||
; NOREGS-LABEL: commute:
|
|
||||||
; NOREGS-NOT: param
|
|
||||||
; NOREGS: .result i32{{$}}
|
|
||||||
; NOREGS-NEXT: i32.call red@FUNCTION{{$}}
|
|
||||||
; NOREGS-NEXT: i32.call green@FUNCTION{{$}}
|
|
||||||
; NOREGS-NEXT: i32.add {{$}}
|
|
||||||
; NOREGS-NEXT: i32.call blue@FUNCTION{{$}}
|
|
||||||
; NOREGS-NEXT: i32.add {{$}}
|
|
||||||
; NOREGS-NEXT: return{{$}}
|
|
||||||
declare i32 @red()
|
declare i32 @red()
|
||||||
declare i32 @green()
|
declare i32 @green()
|
||||||
declare i32 @blue()
|
declare i32 @blue()
|
||||||
@ -421,19 +287,6 @@ define i32 @commute() {
|
|||||||
; CHECK-NEXT: i32.sub $push3=, $pop2, $1
|
; CHECK-NEXT: i32.sub $push3=, $pop2, $1
|
||||||
; CHECK-NEXT: i32.div_s $push4=, $pop3, $1
|
; CHECK-NEXT: i32.div_s $push4=, $pop3, $1
|
||||||
; CHECK-NEXT: return $pop4
|
; CHECK-NEXT: return $pop4
|
||||||
; NOREGS-LABEL: no_stackify_past_use:
|
|
||||||
; NOREGS: get_local 0{{$}}
|
|
||||||
; NOREGS-NEXT: i32.call callee@FUNCTION
|
|
||||||
; NOREGS-NEXT: set_local 1{{$}}
|
|
||||||
; NOREGS-NEXT: get_local 0{{$}}
|
|
||||||
; NOREGS-NEXT: i32.const 1
|
|
||||||
; NOREGS-NEXT: i32.add
|
|
||||||
; NOREGS-NEXT: i32.call callee@FUNCTION
|
|
||||||
; NOREGS-NEXT: get_local 1{{$}}
|
|
||||||
; NOREGS-NEXT: i32.sub
|
|
||||||
; NOREGS-NEXT: get_local 1{{$}}
|
|
||||||
; NOREGS-NEXT: i32.div_s
|
|
||||||
; NOREGS-NEXT: return
|
|
||||||
declare i32 @callee(i32)
|
declare i32 @callee(i32)
|
||||||
define i32 @no_stackify_past_use(i32 %arg) {
|
define i32 @no_stackify_past_use(i32 %arg) {
|
||||||
%tmp1 = call i32 @callee(i32 %arg)
|
%tmp1 = call i32 @callee(i32 %arg)
|
||||||
@ -456,18 +309,6 @@ define i32 @no_stackify_past_use(i32 %arg) {
|
|||||||
; CHECK: i32.add $push3=, $1, $pop2
|
; CHECK: i32.add $push3=, $1, $pop2
|
||||||
; CHECK: i32.mul $push4=, $pop[[L1]], $pop3
|
; CHECK: i32.mul $push4=, $pop[[L1]], $pop3
|
||||||
; CHECK: return $pop4
|
; CHECK: return $pop4
|
||||||
; NOREGS-LABEL: commute_to_fix_ordering:
|
|
||||||
; NOREGS: get_local 0{{$}}
|
|
||||||
; NOREGS: i32.call callee@FUNCTION
|
|
||||||
; NOREGS: tee_local 1
|
|
||||||
; NOREGS: get_local 1{{$}}
|
|
||||||
; NOREGS: get_local 0{{$}}
|
|
||||||
; NOREGS: i32.const 1
|
|
||||||
; NOREGS: i32.add
|
|
||||||
; NOREGS: i32.call callee@FUNCTION
|
|
||||||
; NOREGS: i32.add
|
|
||||||
; NOREGS: i32.mul
|
|
||||||
; NOREGS: return
|
|
||||||
define i32 @commute_to_fix_ordering(i32 %arg) {
|
define i32 @commute_to_fix_ordering(i32 %arg) {
|
||||||
%tmp1 = call i32 @callee(i32 %arg)
|
%tmp1 = call i32 @callee(i32 %arg)
|
||||||
%tmp2 = add i32 %arg, 1
|
%tmp2 = add i32 %arg, 1
|
||||||
@ -484,10 +325,6 @@ define i32 @commute_to_fix_ordering(i32 %arg) {
|
|||||||
; CHECK-NEXT: tee_local $push[[NUM1:[0-9]+]]=, $[[NUM2:[0-9]+]]=, $pop[[NUM0]]{{$}}
|
; CHECK-NEXT: tee_local $push[[NUM1:[0-9]+]]=, $[[NUM2:[0-9]+]]=, $pop[[NUM0]]{{$}}
|
||||||
; CHECK-NEXT: f64.select $push{{[0-9]+}}=, $pop{{[0-9]+}}, $pop[[NUM1]], ${{[0-9]+}}{{$}}
|
; CHECK-NEXT: f64.select $push{{[0-9]+}}=, $pop{{[0-9]+}}, $pop[[NUM1]], ${{[0-9]+}}{{$}}
|
||||||
; CHECK: $[[NUM2]]=,
|
; CHECK: $[[NUM2]]=,
|
||||||
; NOREGS-LABEL: multiple_defs:
|
|
||||||
; NOREGS: f64.add
|
|
||||||
; NOREGS: tee_local
|
|
||||||
; NOREGS: f64.select
|
|
||||||
define void @multiple_defs(i32 %arg, i32 %arg1, i1 %arg2, i1 %arg3, i1 %arg4) {
|
define void @multiple_defs(i32 %arg, i32 %arg1, i1 %arg2, i1 %arg3, i1 %arg4) {
|
||||||
bb:
|
bb:
|
||||||
br label %bb5
|
br label %bb5
|
||||||
@ -530,10 +367,6 @@ exit:
|
|||||||
; CHECK: i32.call $0=, red
|
; CHECK: i32.call $0=, red
|
||||||
; CHECK: i32.const $push0=, 0
|
; CHECK: i32.const $push0=, 0
|
||||||
; CHECK: i32.load $1=, count($pop0)
|
; CHECK: i32.load $1=, count($pop0)
|
||||||
; NOREGS-LABEL: no_stackify_call_past_load:
|
|
||||||
; NOREGS: i32.call red
|
|
||||||
; NOREGS: i32.const 0
|
|
||||||
; NOREGS: i32.load count
|
|
||||||
@count = hidden global i32 0, align 4
|
@count = hidden global i32 0, align 4
|
||||||
define i32 @no_stackify_call_past_load() {
|
define i32 @no_stackify_call_past_load() {
|
||||||
%a = call i32 @red()
|
%a = call i32 @red()
|
||||||
@ -548,10 +381,6 @@ define i32 @no_stackify_call_past_load() {
|
|||||||
; CHECK: i32.store 0($1), $0
|
; CHECK: i32.store 0($1), $0
|
||||||
; CHECK: i32.load {{.*}}, 0($2)
|
; CHECK: i32.load {{.*}}, 0($2)
|
||||||
; CHECK: i32.call {{.*}}, callee@FUNCTION, $0{{$}}
|
; CHECK: i32.call {{.*}}, callee@FUNCTION, $0{{$}}
|
||||||
; NOREGS-LABEL: no_stackify_store_past_load
|
|
||||||
; NOREGS: i32.store 0
|
|
||||||
; NOREGS: i32.load 0
|
|
||||||
; NOREGS: i32.call callee@FUNCTION{{$}}
|
|
||||||
define i32 @no_stackify_store_past_load(i32 %a, i32* %p1, i32* %p2) {
|
define i32 @no_stackify_store_past_load(i32 %a, i32* %p1, i32* %p2) {
|
||||||
store i32 %a, i32* %p1
|
store i32 %a, i32* %p1
|
||||||
%b = load i32, i32* %p2, align 4
|
%b = load i32, i32* %p2, align 4
|
||||||
@ -565,11 +394,6 @@ define i32 @no_stackify_store_past_load(i32 %a, i32* %p1, i32* %p2) {
|
|||||||
; CHECK: i32.call {{.*}}, callee@FUNCTION, $0
|
; CHECK: i32.call {{.*}}, callee@FUNCTION, $0
|
||||||
; CHECK: i32.load $push{{.*}}, 0($2)
|
; CHECK: i32.load $push{{.*}}, 0($2)
|
||||||
; CHECK: return $pop
|
; CHECK: return $pop
|
||||||
; NOREGS-LABEL: store_past_invar_load
|
|
||||||
; NOREGS: i32.store 0
|
|
||||||
; NOREGS: i32.call callee@FUNCTION
|
|
||||||
; NOREGS: i32.load 0
|
|
||||||
; NOREGS: return
|
|
||||||
define i32 @store_past_invar_load(i32 %a, i32* %p1, i32* dereferenceable(4) %p2) {
|
define i32 @store_past_invar_load(i32 %a, i32* %p1, i32* dereferenceable(4) %p2) {
|
||||||
store i32 %a, i32* %p1
|
store i32 %a, i32* %p1
|
||||||
%b = load i32, i32* %p2, !invariant.load !0
|
%b = load i32, i32* %p2, !invariant.load !0
|
||||||
@ -580,9 +404,6 @@ define i32 @store_past_invar_load(i32 %a, i32* %p1, i32* dereferenceable(4) %p2)
|
|||||||
; CHECK-LABEL: ignore_dbg_value:
|
; CHECK-LABEL: ignore_dbg_value:
|
||||||
; CHECK-NEXT: .Lfunc_begin
|
; CHECK-NEXT: .Lfunc_begin
|
||||||
; CHECK-NEXT: unreachable
|
; CHECK-NEXT: unreachable
|
||||||
; NOREGS-LABEL: ignore_dbg_value:
|
|
||||||
; NOREGS-NEXT: .Lfunc_begin
|
|
||||||
; NOREGS-NEXT: unreachable
|
|
||||||
declare void @llvm.dbg.value(metadata, i64, metadata, metadata)
|
declare void @llvm.dbg.value(metadata, i64, metadata, metadata)
|
||||||
define void @ignore_dbg_value() {
|
define void @ignore_dbg_value() {
|
||||||
call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !7, metadata !9), !dbg !10
|
call void @llvm.dbg.value(metadata i32 0, i64 0, metadata !7, metadata !9), !dbg !10
|
||||||
@ -594,8 +415,6 @@ define void @ignore_dbg_value() {
|
|||||||
|
|
||||||
; CHECK-LABEL: no_stackify_past_epilogue:
|
; CHECK-LABEL: no_stackify_past_epilogue:
|
||||||
; CHECK: return ${{[0-9]+}}{{$}}
|
; CHECK: return ${{[0-9]+}}{{$}}
|
||||||
; NOREGS-LABEL: no_stackify_past_epilogue:
|
|
||||||
; NOREGS: return{{$}}
|
|
||||||
declare i32 @use_memory(i32*)
|
declare i32 @use_memory(i32*)
|
||||||
define i32 @no_stackify_past_epilogue() {
|
define i32 @no_stackify_past_epilogue() {
|
||||||
%x = alloca i32
|
%x = alloca i32
|
||||||
@ -610,11 +429,6 @@ define i32 @no_stackify_past_epilogue() {
|
|||||||
; CHECK-NEXT: i32.add $push[[L4:.+]]=, $[[R0:.+]], $pop[[L5]]{{$}}
|
; CHECK-NEXT: i32.add $push[[L4:.+]]=, $[[R0:.+]], $pop[[L5]]{{$}}
|
||||||
; CHECK-NEXT: tee_local $push[[L3:.+]]=, $[[R0]]=, $pop[[L4]]{{$}}
|
; CHECK-NEXT: tee_local $push[[L3:.+]]=, $[[R0]]=, $pop[[L4]]{{$}}
|
||||||
; CHECK-NEXT: i32.ne $push[[L2:.+]]=, $0, $pop[[L3]]{{$}}
|
; CHECK-NEXT: i32.ne $push[[L2:.+]]=, $0, $pop[[L3]]{{$}}
|
||||||
; NOREGS-LABEL: stackify_indvar:
|
|
||||||
; NOREGS: i32.const 1{{$}}
|
|
||||||
; NOREGS-NEXT: i32.add
|
|
||||||
; NOREGS-NEXT: tee_local 2{{$}}
|
|
||||||
; NOREGS-NEXT: i32.ne
|
|
||||||
define void @stackify_indvar(i32 %tmp, i32* %v) #0 {
|
define void @stackify_indvar(i32 %tmp, i32* %v) #0 {
|
||||||
bb:
|
bb:
|
||||||
br label %bb3
|
br label %bb3
|
||||||
@ -637,9 +451,6 @@ bb10: ; preds = %bb9, %bb
|
|||||||
; CHECK-LABEL: stackpointer_dependency:
|
; CHECK-LABEL: stackpointer_dependency:
|
||||||
; CHECK: call {{.+}}, stackpointer_callee@FUNCTION,
|
; CHECK: call {{.+}}, stackpointer_callee@FUNCTION,
|
||||||
; CHECK-NEXT: set_global __stack_pointer,
|
; CHECK-NEXT: set_global __stack_pointer,
|
||||||
; NOREGS-LABEL: stackpointer_dependency:
|
|
||||||
; NOREGS: call stackpointer_callee@FUNCTION
|
|
||||||
; NOREGS: set_global __stack_pointer
|
|
||||||
declare i32 @stackpointer_callee(i8* readnone, i8* readnone)
|
declare i32 @stackpointer_callee(i8* readnone, i8* readnone)
|
||||||
declare i8* @llvm.frameaddress(i32)
|
declare i8* @llvm.frameaddress(i32)
|
||||||
define i32 @stackpointer_dependency(i8* readnone) {
|
define i32 @stackpointer_dependency(i8* readnone) {
|
||||||
@ -656,12 +467,6 @@ define i32 @stackpointer_dependency(i8* readnone) {
|
|||||||
; CHECK-NEXT: i32.load $push[[L0:.+]]=, 0($0)
|
; CHECK-NEXT: i32.load $push[[L0:.+]]=, 0($0)
|
||||||
; CHECK-NEXT: i32.load $push[[L1:.+]]=, 0($pop[[L0]])
|
; CHECK-NEXT: i32.load $push[[L1:.+]]=, 0($pop[[L0]])
|
||||||
; CHECK-NEXT: i32.call_indirect $push{{.+}}=, $pop[[L3]], $1, $pop[[L1]]
|
; CHECK-NEXT: i32.call_indirect $push{{.+}}=, $pop[[L3]], $1, $pop[[L1]]
|
||||||
; NOREGS-LABEL: call_indirect_stackify:
|
|
||||||
; NOREGS: i32.load 0
|
|
||||||
; NOREGS-NEXT: tee_local 0
|
|
||||||
; NOREGS: i32.load 0
|
|
||||||
; NOREGS-NEXT: i32.load 0
|
|
||||||
; NOREGS-NEXT: i32.call_indirect
|
|
||||||
%class.call_indirect = type { i32 (...)** }
|
%class.call_indirect = type { i32 (...)** }
|
||||||
define i32 @call_indirect_stackify(%class.call_indirect** %objptr, i32 %arg) {
|
define i32 @call_indirect_stackify(%class.call_indirect** %objptr, i32 %arg) {
|
||||||
%obj = load %class.call_indirect*, %class.call_indirect** %objptr
|
%obj = load %class.call_indirect*, %class.call_indirect** %objptr
|
||||||
@ -686,4 +491,3 @@ define i32 @call_indirect_stackify(%class.call_indirect** %objptr, i32 %arg) {
|
|||||||
!8 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
|
!8 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
|
||||||
!9 = !DIExpression()
|
!9 = !DIExpression()
|
||||||
!10 = !DILocation(line: 15, column: 6, scope: !5)
|
!10 = !DILocation(line: 15, column: 6, scope: !5)
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -wasm-explicit-locals-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false | FileCheck %s
|
||||||
; RUN: llc < %s -asm-verbose=false -wasm-explicit-locals-codegen-test-mode -fast-isel -fast-isel-abort=1 | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -fast-isel -fast-isel-abort=1 | FileCheck %s
|
||||||
|
|
||||||
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
||||||
target triple = "wasm32-unknown-unknown"
|
target triple = "wasm32-unknown-unknown"
|
||||||
@ -26,7 +26,7 @@ define i32 @return_i32_twice(i32 %a) {
|
|||||||
|
|
||||||
true:
|
true:
|
||||||
store i32 0, i32* null
|
store i32 0, i32* null
|
||||||
ret i32 1
|
ret i32 1
|
||||||
|
|
||||||
false:
|
false:
|
||||||
store i32 2, i32* null
|
store i32 2, i32* null
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
|
||||||
|
|
||||||
; Test that the "returned" attribute is optimized effectively.
|
; Test that the "returned" attribute is optimized effectively.
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
|
||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -fast-isel -fast-isel-abort=1 | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -fast-isel -fast-isel-abort=1 | FileCheck %s
|
||||||
|
|
||||||
; Test that wasm select instruction is selected from LLVM select instruction.
|
; Test that wasm select instruction is selected from LLVM select instruction.
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||||
; RUN: llc < %s -asm-verbose=false -wasm-register-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-explicit-locals | FileCheck %s
|
||||||
|
|
||||||
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
||||||
target triple = "wasm32-unknown-unknown"
|
target triple = "wasm32-unknown-unknown"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: llc < %s -mattr=+sign-ext -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -mattr=+sign-ext -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
|
||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode | FileCheck %s --check-prefix=NOSIGNEXT
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s --check-prefix=NOSIGNEXT
|
||||||
|
|
||||||
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
||||||
target triple = "wasm32-unknown-unknown"
|
target triple = "wasm32-unknown-unknown"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
|
||||||
|
|
||||||
; Test zeroext and signext ABI keywords
|
; Test zeroext and signext ABI keywords
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -mattr=+simd128 | FileCheck %s --check-prefixes CHECK,SIMD128
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -mattr=+simd128 | FileCheck %s --check-prefixes CHECK,SIMD128
|
||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -mattr=+simd128 -fast-isel | FileCheck %s --check-prefixes CHECK,SIMD128
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -mattr=+simd128 -fast-isel | FileCheck %s --check-prefixes CHECK,SIMD128
|
||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -mattr=-simd128 | FileCheck %s --check-prefixes CHECK,NO-SIMD128
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -mattr=-simd128 | FileCheck %s --check-prefixes CHECK,NO-SIMD128
|
||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -mattr=-simd128 -fast-isel | FileCheck %s --check-prefixes CHECK,NO-SIMD128
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -mattr=-simd128 -fast-isel | FileCheck %s --check-prefixes CHECK,NO-SIMD128
|
||||||
|
|
||||||
; Test that basic SIMD128 arithmetic operations assemble as expected.
|
; Test that basic SIMD128 arithmetic operations assemble as expected.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
|
||||||
|
|
||||||
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
||||||
target triple = "wasm32-unknown-unknown"
|
target triple = "wasm32-unknown-unknown"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -mattr=+atomics,+sign-ext -asm-verbose=false -wasm-register-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -mattr=+atomics,+sign-ext -asm-verbose=false -disable-wasm-explicit-locals | FileCheck %s
|
||||||
|
|
||||||
; Test that truncating stores are assembled properly.
|
; Test that truncating stores are assembled properly.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -wasm-register-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-explicit-locals | FileCheck %s
|
||||||
|
|
||||||
; Test that truncating stores are assembled properly.
|
; Test that truncating stores are assembled properly.
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
|
||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode -fast-isel -fast-isel-abort=1 | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -fast-isel -fast-isel-abort=1 | FileCheck %s
|
||||||
|
|
||||||
; Test that basic stores are assembled properly.
|
; Test that basic stores are assembled properly.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -disable-block-placement -verify-machineinstrs | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-block-placement -verify-machineinstrs | FileCheck %s
|
||||||
|
|
||||||
; Test switch instructions. Block placement is disabled because it reorders
|
; Test switch instructions. Block placement is disabled because it reorders
|
||||||
; the blocks in a way that isn't interesting here.
|
; the blocks in a way that isn't interesting here.
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -thread-model=single | FileCheck --check-prefix=SINGLE %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -thread-model=single | FileCheck --check-prefix=SINGLE %s
|
||||||
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
||||||
target triple = "wasm32-unknown-unknown"
|
target triple = "wasm32-unknown-unknown"
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -wasm-register-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-explicit-locals | FileCheck %s
|
||||||
; Test that UMULO works correctly on 64-bit operands.
|
; Test that UMULO works correctly on 64-bit operands.
|
||||||
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
||||||
target triple = "wasm32-unknown-unknown"
|
target triple = "wasm32-unknown-unknown"
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -wasm-explicit-locals-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false | FileCheck %s
|
||||||
|
|
||||||
; Test that function pointer casts that require conversions are not converted
|
; Test that function pointer casts that require conversions are not converted
|
||||||
; to wrappers. In theory some conversions could be supported, but currently no
|
; to wrappers. In theory some conversions could be supported, but currently no
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals | FileCheck %s
|
||||||
|
|
||||||
; Make sure that argument offsets are correct even if some arguments are unused.
|
; Make sure that argument offsets are correct even if some arguments are unused.
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-explicit-locals-codegen-test-mode | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt | FileCheck %s
|
||||||
|
|
||||||
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
target datalayout = "e-m:e-p:32:32-i64:64-n32:64-S128"
|
||||||
target triple = "wasm32-unknown-unknown"
|
target triple = "wasm32-unknown-unknown"
|
||||||
@ -138,7 +138,7 @@ define void @dynamic_alloca(i32 %alloc) {
|
|||||||
; Target independent codegen bumps the stack pointer.
|
; Target independent codegen bumps the stack pointer.
|
||||||
; CHECK: i32.sub
|
; CHECK: i32.sub
|
||||||
; Check that SP is written back to memory after decrement
|
; Check that SP is written back to memory after decrement
|
||||||
; CHECK: set_global __stack_pointer,
|
; CHECK: set_global __stack_pointer,
|
||||||
%r = alloca i32, i32 %alloc
|
%r = alloca i32, i32 %alloc
|
||||||
; Target-independent codegen also calculates the store addr
|
; Target-independent codegen also calculates the store addr
|
||||||
; CHECK: call ext_func_i32@FUNCTION
|
; CHECK: call ext_func_i32@FUNCTION
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -wasm-register-codegen-test-mode -verify-machineinstrs | FileCheck %s
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-fallthrough-return-opt -disable-wasm-explicit-locals -verify-machineinstrs | FileCheck %s
|
||||||
|
|
||||||
; Test varargs constructs.
|
; Test varargs constructs.
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
; RUN: llc < %s -asm-verbose=false -wasm-register-codegen-test-mode | FileCheck %s --check-prefix=TYPEINFONAME
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-explicit-locals | FileCheck %s --check-prefix=TYPEINFONAME
|
||||||
; RUN: llc < %s -asm-verbose=false -wasm-register-codegen-test-mode | FileCheck %s --check-prefix=VTABLE
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-explicit-locals | FileCheck %s --check-prefix=VTABLE
|
||||||
; RUN: llc < %s -asm-verbose=false -wasm-register-codegen-test-mode | FileCheck %s --check-prefix=TYPEINFO
|
; RUN: llc < %s -asm-verbose=false -disable-wasm-explicit-locals | FileCheck %s --check-prefix=TYPEINFO
|
||||||
|
|
||||||
; Test that simple vtables assemble as expected.
|
; Test that simple vtables assemble as expected.
|
||||||
;
|
;
|
||||||
|
@ -11,7 +11,8 @@
|
|||||||
# CHECK: i64.const -1
|
# CHECK: i64.const -1
|
||||||
0x42 0x7F
|
0x42 0x7F
|
||||||
|
|
||||||
# CHECK: i64.load32_u 16:p2align=1
|
# CHECK: i64.load32_u 16, :p2align=1
|
||||||
|
# FIXME: fix p2align output in WebAssemblyInstPrinter
|
||||||
0x35 0x01 0x10
|
0x35 0x01 0x10
|
||||||
|
|
||||||
# CHECK: block
|
# CHECK: block
|
||||||
|
@ -7,33 +7,33 @@ test0:
|
|||||||
.param i32, i64
|
.param i32, i64
|
||||||
.local f32, f64 #, i8x16, i16x8, i32x4, f32x4
|
.local f32, f64 #, i8x16, i16x8, i32x4, f32x4
|
||||||
# Explicit getlocal/setlocal:
|
# Explicit getlocal/setlocal:
|
||||||
get_local 2
|
get_local $push0=, 2
|
||||||
set_local 2
|
set_local 2, $pop0=
|
||||||
# Immediates:
|
# Implicit locals & immediates:
|
||||||
i32.const -1
|
i32.const $0=, -1
|
||||||
f64.const 0x1.999999999999ap1
|
f64.const $3=, 0x1.999999999999ap1
|
||||||
# Indirect addressing:
|
# Indirect addressing:
|
||||||
get_local 0
|
get_local $push1=, 0
|
||||||
f64.store 0
|
f64.store 0($pop1), $3
|
||||||
# Loops, conditionals, binary ops, calls etc:
|
# Loops, conditionals, binary ops, calls etc:
|
||||||
block
|
block
|
||||||
i32.const 1
|
i32.const $push2=, 1
|
||||||
get_local 0
|
get_local $push7=, 0
|
||||||
i32.ge_s
|
i32.ge_s $push0=, $pop2, $pop7
|
||||||
br_if 0 # 0: down to label0
|
br_if 0, $pop0 # 0: down to label0
|
||||||
.LBB0_1:
|
.LBB0_1:
|
||||||
loop # label1:
|
loop # label1:
|
||||||
call something1@FUNCTION
|
call $drop=, something1@FUNCTION
|
||||||
i64.const 1234
|
i64.const $push10=, 1234
|
||||||
i32.call something2@FUNCTION
|
i32.call $push8=, something2@FUNCTION, $pop10
|
||||||
i32.const 0
|
i32.const $push11=, 0
|
||||||
call_indirect
|
call_indirect $pop11
|
||||||
i32.const 1
|
i32.const $push5=, 1
|
||||||
i32.add
|
i32.add $push4=, $pop8, $pop5
|
||||||
tee_local 0
|
tee_local $push3=, 0, $pop4
|
||||||
get_local 0
|
get_local $push9=, 0
|
||||||
i32.lt_s
|
i32.lt_s $push1=, $pop3, $pop9
|
||||||
br_if 0 # 0: up to label1
|
br_if 0, $pop1 # 0: up to label1
|
||||||
.LBB0_2:
|
.LBB0_2:
|
||||||
end_loop
|
end_loop
|
||||||
end_block # label0:
|
end_block # label0:
|
||||||
@ -44,30 +44,30 @@ test0:
|
|||||||
# CHECK-LABEL: test0:
|
# CHECK-LABEL: test0:
|
||||||
# CHECK-NEXT: .param i32, i64
|
# CHECK-NEXT: .param i32, i64
|
||||||
# CHECK-NEXT: .local f32, f64
|
# CHECK-NEXT: .local f32, f64
|
||||||
# CHECK-NEXT: get_local 2
|
# CHECK-NEXT: get_local $push0=, 2
|
||||||
# CHECK-NEXT: set_local 2
|
# CHECK-NEXT: set_local 2, $pop0
|
||||||
# CHECK-NEXT: i32.const -1
|
# CHECK-NEXT: i32.const $0=, -1
|
||||||
# CHECK-NEXT: f64.const 0x1.999999999999ap1
|
# CHECK-NEXT: f64.const $3=, 0x1.999999999999ap1
|
||||||
# CHECK-NEXT: get_local 0
|
# CHECK-NEXT: get_local $push1=, 0
|
||||||
# CHECK-NEXT: f64.store 0:p2align=0
|
# CHECK-NEXT: f64.store 0($pop1):p2align=0, $3
|
||||||
# CHECK-NEXT: block
|
# CHECK-NEXT: block
|
||||||
# CHECK-NEXT: i32.const 1
|
# CHECK-NEXT: i32.const $push2=, 1
|
||||||
# CHECK-NEXT: get_local 0
|
# CHECK-NEXT: get_local $push7=, 0
|
||||||
# CHECK-NEXT: i32.ge_s
|
# CHECK-NEXT: i32.ge_s $push0=, $pop2, $pop7
|
||||||
# CHECK-NEXT: br_if 0 # 0: down to label0
|
# CHECK-NEXT: br_if 0, $pop0 # 0: down to label0
|
||||||
# CHECK-NEXT: .LBB0_1:
|
# CHECK-NEXT: .LBB0_1:
|
||||||
# CHECK-NEXT: loop # label1:
|
# CHECK-NEXT: loop # label1:
|
||||||
# CHECK-NEXT: call something1@FUNCTION
|
# CHECK-NEXT: call something1@FUNCTION
|
||||||
# CHECK-NEXT: i64.const 1234
|
# CHECK-NEXT: i64.const $push10=, 1234
|
||||||
# CHECK-NEXT: i32.call something2@FUNCTION
|
# CHECK-NEXT: i32.call $push8=, something2@FUNCTION
|
||||||
# CHECK-NEXT: i32.const 0
|
# CHECK-NEXT: i32.const $push11=, 0
|
||||||
# CHECK-NEXT: call_indirect
|
# CHECK-NEXT: call_indirect
|
||||||
# CHECK-NEXT: i32.const 1
|
# CHECK-NEXT: i32.const $push5=, 1
|
||||||
# CHECK-NEXT: i32.add
|
# CHECK-NEXT: i32.add $push4=, $pop8, $pop5
|
||||||
# CHECK-NEXT: tee_local 0
|
# CHECK-NEXT: tee_local $push3=, 0, $pop4
|
||||||
# CHECK-NEXT: get_local 0
|
# CHECK-NEXT: get_local $push9=, 0
|
||||||
# CHECK-NEXT: i32.lt_s
|
# CHECK-NEXT: i32.lt_s $push1=, $pop3, $pop9
|
||||||
# CHECK-NEXT: br_if 0 # 0: up to label1
|
# CHECK-NEXT: br_if 0, $pop1 # 0: up to label1
|
||||||
# CHECK-NEXT: .LBB0_2:
|
# CHECK-NEXT: .LBB0_2:
|
||||||
# CHECK-NEXT: end_loop
|
# CHECK-NEXT: end_loop
|
||||||
# CHECK-NEXT: end_block # label0:
|
# CHECK-NEXT: end_block # label0:
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc -filetype=obj -wasm-explicit-locals-codegen-test-mode %s -o - | llvm-readobj -r -expand-relocs | FileCheck %s
|
; RUN: llc -filetype=obj %s -o - | llvm-readobj -r -expand-relocs | FileCheck %s
|
||||||
|
|
||||||
target triple = "wasm32-unknown-unknown"
|
target triple = "wasm32-unknown-unknown"
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
; RUN: llc -filetype=obj -wasm-explicit-locals-codegen-test-mode %s -o %t.o
|
; RUN: llc -filetype=obj %s -o %t.o
|
||||||
; RUN: obj2yaml %t.o | FileCheck %s
|
; RUN: obj2yaml %t.o | FileCheck %s
|
||||||
; RUN: llvm-objdump -t %t.o | FileCheck --check-prefix=CHECK-SYMS %s
|
; RUN: llvm-objdump -t %t.o | FileCheck --check-prefix=CHECK-SYMS %s
|
||||||
|
|
||||||
@ -47,10 +47,10 @@ entry:
|
|||||||
}
|
}
|
||||||
|
|
||||||
; CHECK: - Type: TYPE
|
; CHECK: - Type: TYPE
|
||||||
; CHECK-NEXT: Signatures:
|
; CHECK-NEXT: Signatures:
|
||||||
; CHECK-NEXT: - Index: 0
|
; CHECK-NEXT: - Index: 0
|
||||||
; CHECK-NEXT: ReturnType: I32
|
; CHECK-NEXT: ReturnType: I32
|
||||||
; CHECK-NEXT: ParamTypes:
|
; CHECK-NEXT: ParamTypes:
|
||||||
; CHECK-NEXT: - Type: IMPORT
|
; CHECK-NEXT: - Type: IMPORT
|
||||||
; CHECK-NEXT: Imports:
|
; CHECK-NEXT: Imports:
|
||||||
; CHECK-NEXT: - Module: env
|
; CHECK-NEXT: - Module: env
|
||||||
@ -68,13 +68,13 @@ entry:
|
|||||||
; CHECK-NEXT: - Type: FUNCTION
|
; CHECK-NEXT: - Type: FUNCTION
|
||||||
; CHECK-NEXT: FunctionTypes: [ 0, 0, 0, 0, 0 ]
|
; CHECK-NEXT: FunctionTypes: [ 0, 0, 0, 0, 0 ]
|
||||||
; CHECK-NEXT: - Type: ELEM
|
; CHECK-NEXT: - Type: ELEM
|
||||||
; CHECK-NEXT: Segments:
|
; CHECK-NEXT: Segments:
|
||||||
; CHECK-NEXT: - Offset:
|
; CHECK-NEXT: - Offset:
|
||||||
; CHECK-NEXT: Opcode: I32_CONST
|
; CHECK-NEXT: Opcode: I32_CONST
|
||||||
; CHECK-NEXT: Value: 1
|
; CHECK-NEXT: Value: 1
|
||||||
; CHECK-NEXT: Functions: [ 0 ]
|
; CHECK-NEXT: Functions: [ 0 ]
|
||||||
; CHECK-NEXT: - Type: CODE
|
; CHECK-NEXT: - Type: CODE
|
||||||
; CHECK-NEXT: Relocations:
|
; CHECK-NEXT: Relocations:
|
||||||
; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB
|
; CHECK-NEXT: - Type: R_WEBASSEMBLY_FUNCTION_INDEX_LEB
|
||||||
; CHECK-NEXT: Index: 0
|
; CHECK-NEXT: Index: 0
|
||||||
; CHECK-NEXT: Offset: 0x00000009
|
; CHECK-NEXT: Offset: 0x00000009
|
||||||
@ -93,40 +93,40 @@ entry:
|
|||||||
; CHECK-NEXT: - Type: R_WEBASSEMBLY_TYPE_INDEX_LEB
|
; CHECK-NEXT: - Type: R_WEBASSEMBLY_TYPE_INDEX_LEB
|
||||||
; CHECK-NEXT: Index: 0
|
; CHECK-NEXT: Index: 0
|
||||||
; CHECK-NEXT: Offset: 0x00000037
|
; CHECK-NEXT: Offset: 0x00000037
|
||||||
; CHECK-NEXT: Functions:
|
; CHECK-NEXT: Functions:
|
||||||
; CHECK-NEXT: - Index: 0
|
; CHECK-NEXT: - Index: 0
|
||||||
; CHECK-NEXT: Locals:
|
; CHECK-NEXT: Locals:
|
||||||
; CHECK-NEXT: Body: 41000B
|
; CHECK-NEXT: Body: 41000B
|
||||||
; CHECK-NEXT: - Index: 1
|
; CHECK-NEXT: - Index: 1
|
||||||
; CHECK-NEXT: Locals:
|
; CHECK-NEXT: Locals:
|
||||||
; CHECK-NEXT: Body: 1080808080000B
|
; CHECK-NEXT: Body: 1080808080000B
|
||||||
; CHECK-NEXT: - Index: 2
|
; CHECK-NEXT: - Index: 2
|
||||||
; CHECK-NEXT: Locals:
|
; CHECK-NEXT: Locals:
|
||||||
; CHECK-NEXT: Body: 1080808080000B
|
; CHECK-NEXT: Body: 1080808080000B
|
||||||
; CHECK-NEXT: - Index: 3
|
; CHECK-NEXT: - Index: 3
|
||||||
; CHECK-NEXT: Locals:
|
; CHECK-NEXT: Locals:
|
||||||
; CHECK-NEXT: Body: 410028028880808000118080808000000B
|
; CHECK-NEXT: Body: 410028028880808000118080808000000B
|
||||||
; CHECK-NEXT: - Index: 4
|
; CHECK-NEXT: - Index: 4
|
||||||
; CHECK-NEXT: Locals:
|
; CHECK-NEXT: Locals:
|
||||||
; CHECK-NEXT: Body: 410028029080808000118080808000000B
|
; CHECK-NEXT: Body: 410028029080808000118080808000000B
|
||||||
; CHECK-NEXT: - Type: DATA
|
; CHECK-NEXT: - Type: DATA
|
||||||
; CHECK-NEXT: Relocations:
|
; CHECK-NEXT: Relocations:
|
||||||
; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32
|
; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32
|
||||||
; CHECK-NEXT: Index: 0
|
; CHECK-NEXT: Index: 0
|
||||||
; CHECK-NEXT: Offset: 0x0000000F
|
; CHECK-NEXT: Offset: 0x0000000F
|
||||||
; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32
|
; CHECK-NEXT: - Type: R_WEBASSEMBLY_TABLE_INDEX_I32
|
||||||
; CHECK-NEXT: Index: 3
|
; CHECK-NEXT: Index: 3
|
||||||
; CHECK-NEXT: Offset: 0x00000018
|
; CHECK-NEXT: Offset: 0x00000018
|
||||||
; CHECK-NEXT: Segments:
|
; CHECK-NEXT: Segments:
|
||||||
; CHECK-NEXT: - SectionOffset: 6
|
; CHECK-NEXT: - SectionOffset: 6
|
||||||
; CHECK-NEXT: MemoryIndex: 0
|
; CHECK-NEXT: MemoryIndex: 0
|
||||||
; CHECK-NEXT: Offset:
|
; CHECK-NEXT: Offset:
|
||||||
; CHECK-NEXT: Opcode: I32_CONST
|
; CHECK-NEXT: Opcode: I32_CONST
|
||||||
; CHECK-NEXT: Value: 0
|
; CHECK-NEXT: Value: 0
|
||||||
; CHECK-NEXT: Content: '07000000'
|
; CHECK-NEXT: Content: '07000000'
|
||||||
; CHECK-NEXT: - SectionOffset: 15
|
; CHECK-NEXT: - SectionOffset: 15
|
||||||
; CHECK-NEXT: MemoryIndex: 0
|
; CHECK-NEXT: MemoryIndex: 0
|
||||||
; CHECK-NEXT: Offset:
|
; CHECK-NEXT: Offset:
|
||||||
; CHECK-NEXT: Opcode: I32_CONST
|
; CHECK-NEXT: Opcode: I32_CONST
|
||||||
; CHECK-NEXT: Value: 8
|
; CHECK-NEXT: Value: 8
|
||||||
; CHECK-NEXT: Content: '01000000'
|
; CHECK-NEXT: Content: '01000000'
|
||||||
@ -139,7 +139,7 @@ entry:
|
|||||||
; CHECK-NEXT: - Type: CUSTOM
|
; CHECK-NEXT: - Type: CUSTOM
|
||||||
; CHECK-NEXT: Name: linking
|
; CHECK-NEXT: Name: linking
|
||||||
; CHECK-NEXT: Version: 1
|
; CHECK-NEXT: Version: 1
|
||||||
; CHECK-NEXT: SymbolTable:
|
; CHECK-NEXT: SymbolTable:
|
||||||
; CHECK-NEXT: - Index: 0
|
; CHECK-NEXT: - Index: 0
|
||||||
; CHECK-NEXT: Kind: FUNCTION
|
; CHECK-NEXT: Kind: FUNCTION
|
||||||
; CHECK-NEXT: Name: foo
|
; CHECK-NEXT: Name: foo
|
||||||
@ -194,7 +194,7 @@ entry:
|
|||||||
; CHECK-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN ]
|
; CHECK-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN ]
|
||||||
; CHECK-NEXT: Segment: 0
|
; CHECK-NEXT: Segment: 0
|
||||||
; CHECK-NEXT: Size: 4
|
; CHECK-NEXT: Size: 4
|
||||||
; CHECK-NEXT: SegmentInfo:
|
; CHECK-NEXT: SegmentInfo:
|
||||||
; CHECK-NEXT: - Index: 0
|
; CHECK-NEXT: - Index: 0
|
||||||
; CHECK-NEXT: Name: .data.bar
|
; CHECK-NEXT: Name: .data.bar
|
||||||
; CHECK-NEXT: Alignment: 8
|
; CHECK-NEXT: Alignment: 8
|
||||||
|
@ -101,7 +101,7 @@ TEST(Disassembler, WebAssemblyTest) {
|
|||||||
InstSize = LLVMDisasmInstruction(DCR, BytesP, NumBytes, PC, OutString,
|
InstSize = LLVMDisasmInstruction(DCR, BytesP, NumBytes, PC, OutString,
|
||||||
OutStringSize);
|
OutStringSize);
|
||||||
EXPECT_EQ(InstSize, 3U);
|
EXPECT_EQ(InstSize, 3U);
|
||||||
EXPECT_EQ(StringRef(OutString), "\ti64.load32_u\t16:p2align=1");
|
EXPECT_EQ(StringRef(OutString), "\ti64.load32_u\t16, :p2align=1");
|
||||||
|
|
||||||
LLVMDisasmDispose(DCR);
|
LLVMDisasmDispose(DCR);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user