#include "InstPrinter/WebAssemblyInstPrinter.h"
#include "WebAssembly.h"
#include "WebAssemblyMachineFunctionInfo.h"
+#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrInfo.h"
if (Desc.isVariadic())
for (unsigned i = Desc.getNumOperands(), e = MI->getNumOperands(); i < e;
++i) {
- OS << ", ";
+ if (i != 0)
+ OS << ", ";
printOperand(MI, i, OS);
}
O << "$push" << (WAReg & INT32_MAX);
else
O << "$discard";
- } else if (Op.isImm())
- O << Op.getImm();
- else if (Op.isFPImm())
+ } else if (Op.isImm()) {
+ switch (MI->getOpcode()) {
+ case WebAssembly::PARAM:
+ case WebAssembly::RESULT:
+ case WebAssembly::LOCAL:
+ switch (Op.getImm()) {
+ case MVT::i32: O << "i32"; break;
+ case MVT::i64: O << "i64"; break;
+ case MVT::f32: O << "f32"; break;
+ case MVT::f64: O << "f64"; break;
+ default: llvm_unreachable("unexpected type");
+ }
+ break;
+ default:
+ O << Op.getImm();
+ break;
+ }
+ } else if (Op.isFPImm())
O << toString(APFloat(Op.getFPImm()));
else {
assert(Op.isExpr() && "unknown operand kind in printOperand");
add_llvm_library(LLVMWebAssemblyDesc
WebAssemblyMCAsmInfo.cpp
+ WebAssemblyMCCodeEmitter.cpp
WebAssemblyMCTargetDesc.cpp
)
// Register the MCInstPrinter.
TargetRegistry::RegisterMCInstPrinter(*T, createWebAssemblyMCInstPrinter);
+
+ // Register the MC code emitter
+ TargetRegistry::RegisterMCCodeEmitter(*T, createWebAssemblyMCCodeEmitter);
}
}
class Target;
class Triple;
class raw_ostream;
+class raw_pwrite_stream;
extern Target TheWebAssemblyTarget32;
extern Target TheWebAssemblyTarget64;
+MCCodeEmitter *createWebAssemblyMCCodeEmitter(const MCInstrInfo &MCII,
+ const MCRegisterInfo &MRI,
+ MCContext &Ctx);
+
MCAsmBackend *createWebAssemblyAsmBackend(const Target &T,
const MCRegisterInfo &MRI,
- StringRef TT, StringRef CPU);
+ const Triple &TT, StringRef CPU);
} // end namespace llvm
unsigned AsmVariant, const char *ExtraCode,
raw_ostream &OS) override;
- std::string getRegTypeName(unsigned RegNo) const;
+ MVT getRegType(unsigned RegNo) const;
const char *toString(MVT VT) const;
std::string regToString(const MachineOperand &MO);
};
// Helpers.
//===----------------------------------------------------------------------===//
-std::string WebAssemblyAsmPrinter::getRegTypeName(unsigned RegNo) const {
+MVT WebAssemblyAsmPrinter::getRegType(unsigned RegNo) const {
const TargetRegisterClass *TRC = MRI->getRegClass(RegNo);
for (MVT T : {MVT::i32, MVT::i64, MVT::f32, MVT::f64})
if (TRC->hasType(T))
- return EVT(T).getEVTString();
+ return T;
DEBUG(errs() << "Unknown type for register number: " << RegNo);
llvm_unreachable("Unknown register type");
- return "?";
+ return MVT::Other;
}
std::string WebAssemblyAsmPrinter::regToString(const MachineOperand &MO) {
}
void WebAssemblyAsmPrinter::EmitFunctionBodyStart() {
- SmallString<128> Str;
- raw_svector_ostream OS(Str);
+ if (!MFI->getParams().empty()) {
+ MCInst Param;
+ Param.setOpcode(WebAssembly::PARAM);
+ for (MVT VT : MFI->getParams())
+ Param.addOperand(MCOperand::createImm(VT.SimpleTy));
+ EmitToStreamer(*OutStreamer, Param);
+ }
- for (MVT VT : MFI->getParams())
- OS << "\t" ".param " << toString(VT) << '\n';
SmallVector<MVT, 4> ResultVTs;
const Function &F(*MF->getFunction());
ComputeLegalValueVTs(F, TM, F.getReturnType(), ResultVTs);
// If the return type needs to be legalized it will get converted into
// passing a pointer.
- if (ResultVTs.size() == 1)
- OS << "\t" ".result " << toString(ResultVTs.front()) << '\n';
+ if (ResultVTs.size() == 1) {
+ MCInst Result;
+ Result.setOpcode(WebAssembly::RESULT);
+ Result.addOperand(MCOperand::createImm(ResultVTs.front().SimpleTy));
+ EmitToStreamer(*OutStreamer, Result);
+ }
- bool FirstWAReg = true;
+ bool AnyWARegs = false;
+ MCInst Local;
+ Local.setOpcode(WebAssembly::LOCAL);
for (unsigned Idx = 0, IdxE = MRI->getNumVirtRegs(); Idx != IdxE; ++Idx) {
unsigned VReg = TargetRegisterInfo::index2VirtReg(Idx);
unsigned WAReg = MFI->getWAReg(VReg);
// Don't declare stackified registers.
if (int(WAReg) < 0)
continue;
- if (FirstWAReg)
- OS << "\t" ".local ";
- else
- OS << ", ";
- OS << getRegTypeName(VReg);
- FirstWAReg = false;
+ Local.addOperand(MCOperand::createImm(getRegType(VReg).SimpleTy));
+ AnyWARegs = true;
}
- if (!FirstWAReg)
- OS << '\n';
+ if (AnyWARegs)
+ EmitToStreamer(*OutStreamer, Local);
- // EmitRawText appends a newline, so strip off the last newline.
- StringRef Text = OS.str();
- if (!Text.empty())
- OutStreamer->EmitRawText(Text.substr(0, Text.size() - 1));
AsmPrinter::EmitFunctionBodyStart();
}
StringRef Text = OS.str();
if (!Text.empty())
OutStreamer->EmitRawText(Text.substr(0, Text.size() - 1));
+
+ AsmPrinter::EmitEndOfAsmFile(M);
}
bool WebAssemblyAsmPrinter::PrintAsmOperand(const MachineInstr *MI,
[(set I32:$dst, (WebAssemblywrapper tjumptable:$addr))],
"jump_table\t$dst, $addr">;
+// Function signature and local variable declaration "instructions".
+def PARAM : I<(outs), (ins variable_ops), [], ".param \t">;
+def RESULT : I<(outs), (ins variable_ops), [], ".result \t">;
+def LOCAL : I<(outs), (ins variable_ops), [], ".local \t">;
+
//===----------------------------------------------------------------------===//
// Additional sets of instructions.
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/RegAllocRegistry.h"
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
#include "llvm/IR/Function.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/TargetRegistry.h"
declare void @void_nullary()
; CHECK-LABEL: call_i32_nullary:
-; CHECK-NEXT: .result i32
+; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: call i32_nullary, $push[[NUM:[0-9]+]]{{$}}
; CHECK-NEXT: return $pop[[NUM]]{{$}}
define i32 @call_i32_nullary() {
}
; CHECK-LABEL: call_i64_nullary:
-; CHECK-NEXT: .result i64
+; CHECK-NEXT: .result i64{{$}}
; CHECK-NEXT: call i64_nullary, $push[[NUM:[0-9]+]]{{$}}
; CHECK-NEXT: return $pop[[NUM]]{{$}}
define i64 @call_i64_nullary() {
}
; CHECK-LABEL: call_float_nullary:
-; CHECK-NEXT: .result f32
+; CHECK-NEXT: .result f32{{$}}
; CHECK-NEXT: call float_nullary, $push[[NUM:[0-9]+]]{{$}}
; CHECK-NEXT: return $pop[[NUM]]{{$}}
define float @call_float_nullary() {
}
; CHECK-LABEL: call_double_nullary:
-; CHECK-NEXT: .result f64
+; CHECK-NEXT: .result f64{{$}}
; CHECK-NEXT: call double_nullary, $push[[NUM:[0-9]+]]{{$}}
; CHECK-NEXT: return $pop[[NUM]]{{$}}
define double @call_double_nullary() {
}
; CHECK-LABEL: call_i32_unary:
-; CHECK-NEXT: .param i32
-; CHECK-NEXT: .result i32
+; CHECK-NEXT: .param i32{{$}}
+; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: call i32_unary, $push[[NUM:[0-9]+]], $0{{$}}
; CHECK-NEXT: return $pop[[NUM]]{{$}}
define i32 @call_i32_unary(i32 %a) {
}
; CHECK-LABEL: call_i32_binary:
-; CHECK-NEXT: .param i32
-; CHECK-NEXT: .param i32
-; CHECK-NEXT: .result i32
+; CHECK-NEXT: .param i32, i32{{$}}
+; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: call i32_binary, $push[[NUM:[0-9]+]], $0, $1{{$}}
; CHECK-NEXT: return $pop[[NUM]]{{$}}
define i32 @call_i32_binary(i32 %a, i32 %b) {
}
; CHECK-LABEL: call_indirect_void:
-; CHECK-NEXT: .param i32
+; CHECK-NEXT: .param i32{{$}}
; CHECK-NEXT: call_indirect $0{{$}}
; CHECK-NEXT: return{{$}}
define void @call_indirect_void(void ()* %callee) {
}
; CHECK-LABEL: call_indirect_i32:
-; CHECK-NEXT: .param i32
-; CHECK-NEXT: .result i32
+; CHECK-NEXT: .param i32{{$}}
+; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: call_indirect $0, $push[[NUM:[0-9]+]]{{$}}
; CHECK-NEXT: return $pop[[NUM]]{{$}}
define i32 @call_indirect_i32(i32 ()* %callee) {
target triple = "wasm32-unknown-unknown"
; CHECK-LABEL: ord_f32:
-; CHECK-NEXT: .param f32{{$}}
-; CHECK-NEXT: .param f32{{$}}
+; CHECK-NEXT: .param f32, f32{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: f32.eq $push[[NUM0:[0-9]+]], $0, $0{{$}}
; CHECK-NEXT: f32.eq $push[[NUM1:[0-9]+]], $1, $1{{$}}
}
; CHECK-LABEL: uno_f32:
-; CHECK-NEXT: .param f32{{$}}
-; CHECK-NEXT: .param f32{{$}}
+; CHECK-NEXT: .param f32, f32{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: f32.ne $push[[NUM0:[0-9]+]], $0, $0{{$}}
; CHECK-NEXT: f32.ne $push[[NUM1:[0-9]+]], $1, $1{{$}}
}
; CHECK-LABEL: oeq_f32:
-; CHECK-NEXT: .param f32{{$}}
-; CHECK-NEXT: .param f32{{$}}
+; CHECK-NEXT: .param f32, f32{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: f32.eq $push[[NUM:[0-9]+]], $0, $1{{$}}
; CHECK-NEXT: return $pop[[NUM]]{{$}}
; Expanded comparisons, which also check for NaN.
; CHECK-LABEL: ueq_f32:
-; CHECK-NEXT: .param f32{{$}}
-; CHECK-NEXT: .param f32{{$}}
+; CHECK-NEXT: .param f32, f32{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: f32.eq $push[[NUM0:[0-9]+]], $0, $1{{$}}
; CHECK-NEXT: f32.ne $push[[NUM1:[0-9]+]], $0, $0{{$}}
; CHECK-LABEL: one_f32:
; CHECK-NEXT: .param f32
-; CHECK-NEXT: .param f32
; CHECK-NEXT: .result i32
; CHECK-NEXT: f32.ne $push[[NUM0:[0-9]+]], $0, $1{{$}}
; CHECK-NEXT: f32.eq $push[[NUM1:[0-9]+]], $0, $0{{$}}
}
; CHECK-LABEL: ult_f32:
-; CHECK-NEXT: .param f32{{$}}
-; CHECK-NEXT: .param f32{{$}}
+; CHECK-NEXT: .param f32, f32{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: f32.lt $push[[NUM0:[0-9]+]], $0, $1{{$}}
; CHECK-NEXT: f32.ne $push[[NUM1:[0-9]+]], $0, $0{{$}}
}
; CHECK-LABEL: ule_f32:
-; CHECK-NEXT: .param f32{{$}}
-; CHECK-NEXT: .param f32{{$}}
+; CHECK-NEXT: .param f32, f32{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: f32.le $push[[NUM0:[0-9]+]], $0, $1{{$}}
; CHECK-NEXT: f32.ne $push[[NUM1:[0-9]+]], $0, $0{{$}}
}
; CHECK-LABEL: ugt_f32:
-; CHECK-NEXT: .param f32{{$}}
-; CHECK-NEXT: .param f32{{$}}
+; CHECK-NEXT: .param f32, f32{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: f32.gt $push[[NUM0:[0-9]+]], $0, $1{{$}}
; CHECK-NEXT: f32.ne $push[[NUM1:[0-9]+]], $0, $0{{$}}
}
; CHECK-LABEL: uge_f32:
-; CHECK-NEXT: .param f32{{$}}
-; CHECK-NEXT: .param f32{{$}}
+; CHECK-NEXT: .param f32, f32{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: f32.ge $push[[NUM0:[0-9]+]], $0, $1{{$}}
; CHECK-NEXT: f32.ne $push[[NUM1:[0-9]+]], $0, $0{{$}}
target triple = "wasm32-unknown-unknown"
; CHECK-LABEL: ord_f64:
-; CHECK-NEXT: .param f64{{$}}
-; CHECK-NEXT: .param f64{{$}}
+; CHECK-NEXT: .param f64, f64{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: f64.eq $push[[NUM0:[0-9]+]], $0, $0{{$}}
; CHECK-NEXT: f64.eq $push[[NUM1:[0-9]+]], $1, $1{{$}}
}
; CHECK-LABEL: uno_f64:
-; CHECK-NEXT: .param f64{{$}}
-; CHECK-NEXT: .param f64{{$}}
+; CHECK-NEXT: .param f64, f64{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: f64.ne $push[[NUM0:[0-9]+]], $0, $0{{$}}
; CHECK-NEXT: f64.ne $push[[NUM1:[0-9]+]], $1, $1{{$}}
}
; CHECK-LABEL: oeq_f64:
-; CHECK-NEXT: .param f64{{$}}
-; CHECK-NEXT: .param f64{{$}}
+; CHECK-NEXT: .param f64, f64{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: f64.eq $push[[NUM:[0-9]+]], $0, $1{{$}}
; CHECK-NEXT: return $pop[[NUM]]{{$}}
; Expanded comparisons, which also check for NaN.
; CHECK-LABEL: ueq_f64:
-; CHECK-NEXT: .param f64{{$}}
-; CHECK-NEXT: .param f64{{$}}
+; CHECK-NEXT: .param f64, f64{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: f64.eq $push[[NUM0:[0-9]+]], $0, $1{{$}}
; CHECK-NEXT: f64.ne $push[[NUM1:[0-9]+]], $0, $0{{$}}
; CHECK-LABEL: one_f64:
; CHECK-NEXT: .param f64
-; CHECK-NEXT: .param f64
; CHECK-NEXT: .result i32
; CHECK-NEXT: f64.ne $push[[NUM0:[0-9]+]], $0, $1{{$}}
; CHECK-NEXT: f64.eq $push[[NUM1:[0-9]+]], $0, $0{{$}}
}
; CHECK-LABEL: ult_f64:
-; CHECK-NEXT: .param f64{{$}}
-; CHECK-NEXT: .param f64{{$}}
+; CHECK-NEXT: .param f64, f64{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: f64.lt $push[[NUM0:[0-9]+]], $0, $1{{$}}
; CHECK-NEXT: f64.ne $push[[NUM1:[0-9]+]], $0, $0{{$}}
}
; CHECK-LABEL: ule_f64:
-; CHECK-NEXT: .param f64{{$}}
-; CHECK-NEXT: .param f64{{$}}
+; CHECK-NEXT: .param f64, f64{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: f64.le $push[[NUM0:[0-9]+]], $0, $1{{$}}
; CHECK-NEXT: f64.ne $push[[NUM1:[0-9]+]], $0, $0{{$}}
}
; CHECK-LABEL: ugt_f64:
-; CHECK-NEXT: .param f64{{$}}
-; CHECK-NEXT: .param f64{{$}}
+; CHECK-NEXT: .param f64, f64{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: f64.gt $push[[NUM0:[0-9]+]], $0, $1{{$}}
; CHECK-NEXT: f64.ne $push[[NUM1:[0-9]+]], $0, $0{{$}}
}
; CHECK-LABEL: uge_f64:
-; CHECK-NEXT: .param f64{{$}}
-; CHECK-NEXT: .param f64{{$}}
+; CHECK-NEXT: .param f64, f64{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: f64.ge $push[[NUM0:[0-9]+]], $0, $1{{$}}
; CHECK-NEXT: f64.ne $push[[NUM1:[0-9]+]], $0, $0{{$}}
target triple = "wasm32-unknown-unknown"
; CHECK-LABEL: eq_i32:
-; CHECK-NEXT: .param i32{{$}}
-; CHECK-NEXT: .param i32{{$}}
+; CHECK-NEXT: .param i32, i32{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: i32.eq $push[[NUM:[0-9]+]], $0, $1{{$}}
; CHECK-NEXT: return $pop[[NUM]]{{$}}
target triple = "wasm32-unknown-unknown"
; CHECK-LABEL: eq_i64:
-; CHECK-NEXT: .param i64{{$}}
-; CHECK-NEXT: .param i64{{$}}
+; CHECK-NEXT: .param i64, i64{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: i64.eq $push[[NUM:[0-9]+]], $0, $1{{$}}
; CHECK-NEXT: return $pop[[NUM]]{{$}}
define void @foo(i32* nocapture %a, i32 %w, i32 %h) {
; CHECK-LABEL: foo:
-; CHECK-NEXT: .param i32
-; CHECK-NEXT: .param i32
-; CHECK-NEXT: .param i32
+; CHECK-NEXT: .param i32, i32, i32
; CHECK-NEXT: .local i32, i32, i32, i32, i32, i32, i32, i32, i32{{$}}
entry:
%cmp.19 = icmp sgt i32 %h, 0
declare float @llvm.rint.f32(float)
; CHECK-LABEL: fadd32:
-; CHECK-NEXT: .param f32{{$}}
-; CHECK-NEXT: .param f32{{$}}
+; CHECK-NEXT: .param f32, f32{{$}}
; CHECK-NEXT: .result f32{{$}}
; CHECK-NEXT: f32.add $push0, $0, $1{{$}}
; CHECK-NEXT: return $pop0{{$}}
declare double @llvm.rint.f64(double)
; CHECK-LABEL: fadd64:
-; CHECK-NEXT: .param f64{{$}}
-; CHECK-NEXT: .param f64{{$}}
+; CHECK-NEXT: .param f64, f64{{$}}
; CHECK-NEXT: .result f64{{$}}
; CHECK-NEXT: f64.add $push0, $0, $1{{$}}
; CHECK-NEXT: return $pop0{{$}}
}
; CHECK-LABEL: f2:
-; CHECK-NEXT: .param i32{{$}}
-; CHECK-NEXT: .param f32{{$}}
+; CHECK-NEXT: .param i32, f32{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: i32.const $push[[NUM:[0-9]+]], 0{{$}}
; CHECK-NEXT: return $pop[[NUM]]{{$}}
}
; CHECK-LABEL: f3:
-; CHECK-NEXT: .param i32{{$}}
-; CHECK-NEXT: .param f32{{$}}
-; CHECK-NOT: .local
+; CHECK-NEXT: .param i32, f32{{$}}
+; CHECK-NOT: local
; CHECK-NEXT: return{{$}}
; CHECK: .size f3,
define void @f3(i32 %p1, float %p2) {
; CHECK-LABEL: f4:
; CHECK-NEXT: .param i32{{$}}
; CHECK-NEXT: .result i32{{$}}
-; CHECK-NEXT: .local
+; CHECK-NEXT: local
define i32 @f4(i32 %x) {
entry:
%c = trunc i32 %x to i1
declare i32 @llvm.ctpop.i32(i32)
; CHECK-LABEL: add32:
-; CHECK-NEXT: .param i32{{$}}
-; CHECK-NEXT: .param i32{{$}}
+; CHECK-NEXT: .param i32, i32{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: i32.add $push0, $0, $1{{$}}
; CHECK-NEXT: return $pop0{{$}}
}
; CHECK-LABEL: sub32:
-; CHECK-NEXT: .param i32{{$}}
-; CHECK-NEXT: .param i32{{$}}
+; CHECK-NEXT: .param i32, i32{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: i32.sub $push0, $0, $1{{$}}
; CHECK-NEXT: return $pop0{{$}}
}
; CHECK-LABEL: mul32:
-; CHECK-NEXT: .param i32{{$}}
-; CHECK-NEXT: .param i32{{$}}
+; CHECK-NEXT: .param i32, i32{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: i32.mul $push0, $0, $1{{$}}
; CHECK-NEXT: return $pop0{{$}}
}
; CHECK-LABEL: sdiv32:
-; CHECK-NEXT: .param i32{{$}}
-; CHECK-NEXT: .param i32{{$}}
+; CHECK-NEXT: .param i32, i32{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: i32.div_s $push0, $0, $1{{$}}
; CHECK-NEXT: return $pop0{{$}}
}
; CHECK-LABEL: udiv32:
-; CHECK-NEXT: .param i32{{$}}
-; CHECK-NEXT: .param i32{{$}}
+; CHECK-NEXT: .param i32, i32{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: i32.div_u $push0, $0, $1{{$}}
; CHECK-NEXT: return $pop0{{$}}
}
; CHECK-LABEL: srem32:
-; CHECK-NEXT: .param i32{{$}}
-; CHECK-NEXT: .param i32{{$}}
+; CHECK-NEXT: .param i32, i32{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: i32.rem_s $push0, $0, $1{{$}}
; CHECK-NEXT: return $pop0{{$}}
}
; CHECK-LABEL: urem32:
-; CHECK-NEXT: .param i32{{$}}
-; CHECK-NEXT: .param i32{{$}}
+; CHECK-NEXT: .param i32, i32{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: i32.rem_u $push0, $0, $1{{$}}
; CHECK-NEXT: return $pop0{{$}}
}
; CHECK-LABEL: and32:
-; CHECK-NEXT: .param i32{{$}}
-; CHECK-NEXT: .param i32{{$}}
+; CHECK-NEXT: .param i32, i32{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: i32.and $push0, $0, $1{{$}}
; CHECK-NEXT: return $pop0{{$}}
}
; CHECK-LABEL: or32:
-; CHECK-NEXT: .param i32{{$}}
-; CHECK-NEXT: .param i32{{$}}
+; CHECK-NEXT: .param i32, i32{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: i32.or $push0, $0, $1{{$}}
; CHECK-NEXT: return $pop0{{$}}
}
; CHECK-LABEL: xor32:
-; CHECK-NEXT: .param i32{{$}}
-; CHECK-NEXT: .param i32{{$}}
+; CHECK-NEXT: .param i32, i32{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: i32.xor $push0, $0, $1{{$}}
; CHECK-NEXT: return $pop0{{$}}
}
; CHECK-LABEL: shl32:
-; CHECK-NEXT: .param i32{{$}}
-; CHECK-NEXT: .param i32{{$}}
+; CHECK-NEXT: .param i32, i32{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: i32.shl $push0, $0, $1{{$}}
; CHECK-NEXT: return $pop0{{$}}
}
; CHECK-LABEL: shr32:
-; CHECK-NEXT: .param i32{{$}}
-; CHECK-NEXT: .param i32{{$}}
+; CHECK-NEXT: .param i32, i32{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: i32.shr_u $push0, $0, $1{{$}}
; CHECK-NEXT: return $pop0{{$}}
}
; CHECK-LABEL: sar32:
-; CHECK-NEXT: .param i32{{$}}
-; CHECK-NEXT: .param i32{{$}}
+; CHECK-NEXT: .param i32, i32{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: i32.shr_s $push0, $0, $1{{$}}
; CHECK-NEXT: return $pop0{{$}}
declare i64 @llvm.ctpop.i64(i64)
; CHECK-LABEL: add64:
-; CHECK-NEXT: .param i64{{$}}
-; CHECK-NEXT: .param i64{{$}}
+; CHECK-NEXT: .param i64, i64{{$}}
; CHECK-NEXT: .result i64{{$}}
; CHECK-NEXT: i64.add $push0, $0, $1{{$}}
; CHECK-NEXT: return $pop0{{$}}
}
; CHECK-LABEL: sub64:
-; CHECK-NEXT: .param i64{{$}}
-; CHECK-NEXT: .param i64{{$}}
+; CHECK-NEXT: .param i64, i64{{$}}
; CHECK-NEXT: .result i64{{$}}
; CHECK-NEXT: i64.sub $push0, $0, $1{{$}}
; CHECK-NEXT: return $pop0{{$}}
}
; CHECK-LABEL: mul64:
-; CHECK-NEXT: .param i64{{$}}
-; CHECK-NEXT: .param i64{{$}}
+; CHECK-NEXT: .param i64, i64{{$}}
; CHECK-NEXT: .result i64{{$}}
; CHECK-NEXT: i64.mul $push0, $0, $1{{$}}
; CHECK-NEXT: return $pop0{{$}}
}
; CHECK-LABEL: sdiv64:
-; CHECK-NEXT: .param i64{{$}}
-; CHECK-NEXT: .param i64{{$}}
+; CHECK-NEXT: .param i64, i64{{$}}
; CHECK-NEXT: .result i64{{$}}
; CHECK-NEXT: i64.div_s $push0, $0, $1{{$}}
; CHECK-NEXT: return $pop0{{$}}
}
; CHECK-LABEL: udiv64:
-; CHECK-NEXT: .param i64{{$}}
-; CHECK-NEXT: .param i64{{$}}
+; CHECK-NEXT: .param i64, i64{{$}}
; CHECK-NEXT: .result i64{{$}}
; CHECK-NEXT: i64.div_u $push0, $0, $1{{$}}
; CHECK-NEXT: return $pop0{{$}}
}
; CHECK-LABEL: srem64:
-; CHECK-NEXT: .param i64{{$}}
-; CHECK-NEXT: .param i64{{$}}
+; CHECK-NEXT: .param i64, i64{{$}}
; CHECK-NEXT: .result i64{{$}}
; CHECK-NEXT: i64.rem_s $push0, $0, $1{{$}}
; CHECK-NEXT: return $pop0{{$}}
}
; CHECK-LABEL: urem64:
-; CHECK-NEXT: .param i64{{$}}
-; CHECK-NEXT: .param i64{{$}}
+; CHECK-NEXT: .param i64, i64{{$}}
; CHECK-NEXT: .result i64{{$}}
; CHECK-NEXT: i64.rem_u $push0, $0, $1{{$}}
; CHECK-NEXT: return $pop0{{$}}
}
; CHECK-LABEL: and64:
-; CHECK-NEXT: .param i64{{$}}
-; CHECK-NEXT: .param i64{{$}}
+; CHECK-NEXT: .param i64, i64{{$}}
; CHECK-NEXT: .result i64{{$}}
; CHECK-NEXT: i64.and $push0, $0, $1{{$}}
; CHECK-NEXT: return $pop0{{$}}
}
; CHECK-LABEL: or64:
-; CHECK-NEXT: .param i64{{$}}
-; CHECK-NEXT: .param i64{{$}}
+; CHECK-NEXT: .param i64, i64{{$}}
; CHECK-NEXT: .result i64{{$}}
; CHECK-NEXT: i64.or $push0, $0, $1{{$}}
; CHECK-NEXT: return $pop0{{$}}
}
; CHECK-LABEL: xor64:
-; CHECK-NEXT: .param i64{{$}}
-; CHECK-NEXT: .param i64{{$}}
+; CHECK-NEXT: .param i64, i64{{$}}
; CHECK-NEXT: .result i64{{$}}
; CHECK-NEXT: i64.xor $push0, $0, $1{{$}}
; CHECK-NEXT: return $pop0{{$}}
}
; CHECK-LABEL: shl64:
-; CHECK-NEXT: .param i64{{$}}
-; CHECK-NEXT: .param i64{{$}}
+; CHECK-NEXT: .param i64, i64{{$}}
; CHECK-NEXT: .result i64{{$}}
; CHECK-NEXT: i64.shl $push0, $0, $1{{$}}
; CHECK-NEXT: return $pop0{{$}}
}
; CHECK-LABEL: shr64:
-; CHECK-NEXT: .param i64{{$}}
-; CHECK-NEXT: .param i64{{$}}
+; CHECK-NEXT: .param i64, i64{{$}}
; CHECK-NEXT: .result i64{{$}}
; CHECK-NEXT: i64.shr_u $push0, $0, $1{{$}}
; CHECK-NEXT: return $pop0{{$}}
}
; CHECK-LABEL: sar64:
-; CHECK-NEXT: .param i64{{$}}
-; CHECK-NEXT: .param i64{{$}}
+; CHECK-NEXT: .param i64, i64{{$}}
; CHECK-NEXT: .result i64{{$}}
; CHECK-NEXT: i64.shr_s $push0, $0, $1{{$}}
; CHECK-NEXT: return $pop0{{$}}
}
; CHECK-LABEL: bar:
-; CHECK-NEXT: .param i32{{$}}
-; CHECK-NEXT: .param i32{{$}}
+; CHECK-NEXT: .param i32, i32{{$}}
; CHECK-NEXT: #APP{{$}}
; CHECK-NEXT: # $1 = bbb($0){{$}}
; CHECK-NEXT: #NO_APP{{$}}
target triple = "wasm32-unknown-unknown"
; CHECK-LABEL: sti32:
-; CHECK-NEXT: .param i32{{$}}
-; CHECK-NEXT: .param i32{{$}}
+; CHECK-NEXT: .param i32, i32{{$}}
; CHECK-NEXT: i32.store $0, $1{{$}}
; CHECK-NEXT: return{{$}}
define void @sti32(i32 *%p, i32 %v) {
}
; CHECK-LABEL: sti64:
-; CHECK-NEXT: .param i32{{$}}
-; CHECK-NEXT: .param i64{{$}}
+; CHECK-NEXT: .param i32, i64{{$}}
; CHECK-NEXT: i64.store $0, $1{{$}}
; CHECK-NEXT: return{{$}}
define void @sti64(i64 *%p, i64 %v) {
}
; CHECK-LABEL: stf32:
-; CHECK-NEXT: .param i32{{$}}
-; CHECK-NEXT: .param f32{{$}}
+; CHECK-NEXT: .param i32, f32{{$}}
; CHECK-NEXT: f32.store $0, $1{{$}}
; CHECK-NEXT: return{{$}}
define void @stf32(float *%p, float %v) {
}
; CHECK-LABEL: stf64:
-; CHECK-NEXT: .param i32{{$}}
-; CHECK-NEXT: .param f64{{$}}
+; CHECK-NEXT: .param i32, f64{{$}}
; CHECK-NEXT: f64.store $0, $1{{$}}
; CHECK-NEXT: return{{$}}
define void @stf64(double *%p, double %v) {
target triple = "wasm32-unknown-unknown"
; CHECK-LABEL: unused_first:
-; CHECK-NEXT: .param i32{{$}}
-; CHECK-NEXT: .param i32{{$}}
+; CHECK-NEXT: .param i32, i32{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: return $1{{$}}
define i32 @unused_first(i32 %x, i32 %y) {
}
; CHECK-LABEL: unused_second:
-; CHECK-NEXT: .param i32{{$}}
-; CHECK-NEXT: .param i32{{$}}
+; CHECK-NEXT: .param i32, i32{{$}}
; CHECK-NEXT: .result i32{{$}}
; CHECK-NEXT: return $0{{$}}
define i32 @unused_second(i32 %x, i32 %y) {