You've already forked linux-packaging-mono
Imported Upstream version 5.18.0.167
Former-commit-id: 289509151e0fee68a1b591a20c9f109c3c789d3a
This commit is contained in:
parent
e19d552987
commit
b084638f15
@ -1,57 +0,0 @@
|
||||
set(LLVM_TARGET_DEFINITIONS WebAssembly.td)
|
||||
|
||||
tablegen(LLVM WebAssemblyGenAsmWriter.inc -gen-asm-writer)
|
||||
tablegen(LLVM WebAssemblyGenDAGISel.inc -gen-dag-isel)
|
||||
tablegen(LLVM WebAssemblyGenFastISel.inc -gen-fast-isel)
|
||||
tablegen(LLVM WebAssemblyGenInstrInfo.inc -gen-instr-info)
|
||||
tablegen(LLVM WebAssemblyGenMCCodeEmitter.inc -gen-emitter)
|
||||
tablegen(LLVM WebAssemblyGenRegisterInfo.inc -gen-register-info)
|
||||
tablegen(LLVM WebAssemblyGenSubtargetInfo.inc -gen-subtarget)
|
||||
add_public_tablegen_target(WebAssemblyCommonTableGen)
|
||||
|
||||
add_llvm_target(WebAssemblyCodeGen
|
||||
WebAssemblyArgumentMove.cpp
|
||||
WebAssemblyAsmPrinter.cpp
|
||||
WebAssemblyCallIndirectFixup.cpp
|
||||
WebAssemblyCFGStackify.cpp
|
||||
WebAssemblyCFGSort.cpp
|
||||
WebAssemblyExplicitLocals.cpp
|
||||
WebAssemblyFastISel.cpp
|
||||
WebAssemblyFixIrreducibleControlFlow.cpp
|
||||
WebAssemblyFixFunctionBitcasts.cpp
|
||||
WebAssemblyFrameLowering.cpp
|
||||
WebAssemblyISelDAGToDAG.cpp
|
||||
WebAssemblyISelLowering.cpp
|
||||
WebAssemblyInstrInfo.cpp
|
||||
WebAssemblyLowerBrUnless.cpp
|
||||
WebAssemblyLowerEmscriptenEHSjLj.cpp
|
||||
WebAssemblyLowerGlobalDtors.cpp
|
||||
WebAssemblyMachineFunctionInfo.cpp
|
||||
WebAssemblyMCInstLower.cpp
|
||||
WebAssemblyOptimizeLiveIntervals.cpp
|
||||
WebAssemblyOptimizeReturned.cpp
|
||||
WebAssemblyPeephole.cpp
|
||||
WebAssemblyPrepareForLiveIntervals.cpp
|
||||
WebAssemblyRegisterInfo.cpp
|
||||
WebAssemblyRegColoring.cpp
|
||||
WebAssemblyRegNumbering.cpp
|
||||
WebAssemblyRegStackify.cpp
|
||||
WebAssemblyReplacePhysRegs.cpp
|
||||
WebAssemblyRuntimeLibcallSignatures.cpp
|
||||
WebAssemblySelectionDAGInfo.cpp
|
||||
WebAssemblySetP2AlignOperands.cpp
|
||||
WebAssemblyStoreResults.cpp
|
||||
WebAssemblySubtarget.cpp
|
||||
WebAssemblyTargetMachine.cpp
|
||||
WebAssemblyTargetObjectFile.cpp
|
||||
WebAssemblyTargetTransformInfo.cpp
|
||||
WebAssemblyUtilities.cpp
|
||||
|
||||
DEPENDS
|
||||
intrinsics_gen
|
||||
)
|
||||
|
||||
add_subdirectory(Disassembler)
|
||||
add_subdirectory(InstPrinter)
|
||||
add_subdirectory(MCTargetDesc)
|
||||
add_subdirectory(TargetInfo)
|
@ -1,3 +0,0 @@
|
||||
add_llvm_library(LLVMWebAssemblyDisassembler
|
||||
WebAssemblyDisassembler.cpp
|
||||
)
|
@ -1,23 +0,0 @@
|
||||
;===-- ./lib/Target/WebAssembly/Disassembler/LLVMBuild.txt -----*- Conf -*--===;
|
||||
;
|
||||
; The LLVM Compiler Infrastructure
|
||||
;
|
||||
; This file is distributed under the University of Illinois Open Source
|
||||
; License. See LICENSE.TXT for details.
|
||||
;
|
||||
;===------------------------------------------------------------------------===;
|
||||
;
|
||||
; This is an LLVMBuild description file for the components in this subdirectory.
|
||||
;
|
||||
; For more information on the LLVMBuild system, please see:
|
||||
;
|
||||
; http://llvm.org/docs/LLVMBuild.html
|
||||
;
|
||||
;===------------------------------------------------------------------------===;
|
||||
|
||||
[component_0]
|
||||
type = Library
|
||||
name = WebAssemblyDisassembler
|
||||
parent = WebAssembly
|
||||
required_libraries = MCDisassembler WebAssemblyInfo Support
|
||||
add_to_library_groups = WebAssembly
|
@ -1,70 +0,0 @@
|
||||
//==- WebAssemblyDisassembler.cpp - Disassembler for WebAssembly -*- C++ -*-==//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// \brief This file is part of the WebAssembly Disassembler.
|
||||
///
|
||||
/// It contains code to translate the data produced by the decoder into
|
||||
/// MCInsts.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
|
||||
#include "WebAssembly.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/MC/MCInstrInfo.h"
|
||||
#include "llvm/MC/MCSubtargetInfo.h"
|
||||
#include "llvm/MC/MCSymbol.h"
|
||||
#include "llvm/Support/Endian.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "wasm-disassembler"
|
||||
|
||||
namespace {
|
||||
class WebAssemblyDisassembler final : public MCDisassembler {
|
||||
std::unique_ptr<const MCInstrInfo> MCII;
|
||||
|
||||
DecodeStatus getInstruction(MCInst &Instr, uint64_t &Size,
|
||||
ArrayRef<uint8_t> Bytes, uint64_t Address,
|
||||
raw_ostream &VStream,
|
||||
raw_ostream &CStream) const override;
|
||||
|
||||
public:
|
||||
WebAssemblyDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
|
||||
std::unique_ptr<const MCInstrInfo> MCII)
|
||||
: MCDisassembler(STI, Ctx), MCII(std::move(MCII)) {}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
static MCDisassembler *createWebAssemblyDisassembler(const Target &T,
|
||||
const MCSubtargetInfo &STI,
|
||||
MCContext &Ctx) {
|
||||
std::unique_ptr<const MCInstrInfo> MCII(T.createMCInstrInfo());
|
||||
return new WebAssemblyDisassembler(STI, Ctx, std::move(MCII));
|
||||
}
|
||||
|
||||
extern "C" void LLVMInitializeWebAssemblyDisassembler() {
|
||||
// Register the disassembler for each target.
|
||||
TargetRegistry::RegisterMCDisassembler(getTheWebAssemblyTarget32(),
|
||||
createWebAssemblyDisassembler);
|
||||
TargetRegistry::RegisterMCDisassembler(getTheWebAssemblyTarget64(),
|
||||
createWebAssemblyDisassembler);
|
||||
}
|
||||
|
||||
MCDisassembler::DecodeStatus WebAssemblyDisassembler::getInstruction(
|
||||
MCInst &MI, uint64_t &Size, ArrayRef<uint8_t> Bytes, uint64_t /*Address*/,
|
||||
raw_ostream &OS, raw_ostream &CS) const {
|
||||
|
||||
// TODO: Implement disassembly.
|
||||
|
||||
return MCDisassembler::Fail;
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
add_llvm_library(LLVMWebAssemblyAsmPrinter
|
||||
WebAssemblyInstPrinter.cpp
|
||||
)
|
@ -1,23 +0,0 @@
|
||||
;===- ./lib/Target/WebAssembly/InstPrinter/LLVMBuild.txt -------*- Conf -*--===;
|
||||
;
|
||||
; The LLVM Compiler Infrastructure
|
||||
;
|
||||
; This file is distributed under the University of Illinois Open Source
|
||||
; License. See LICENSE.TXT for details.
|
||||
;
|
||||
;===------------------------------------------------------------------------===;
|
||||
;
|
||||
; This is an LLVMBuild description file for the components in this subdirectory.
|
||||
;
|
||||
; For more information on the LLVMBuild system, please see:
|
||||
;
|
||||
; http://llvm.org/docs/LLVMBuild.html
|
||||
;
|
||||
;===------------------------------------------------------------------------===;
|
||||
|
||||
[component_0]
|
||||
type = Library
|
||||
name = WebAssemblyAsmPrinter
|
||||
parent = WebAssembly
|
||||
required_libraries = MC Support
|
||||
add_to_library_groups = WebAssembly
|
@ -1,258 +0,0 @@
|
||||
//=- WebAssemblyInstPrinter.cpp - WebAssembly assembly instruction printing -=//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// \brief Print MCInst instructions to wasm format.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "InstPrinter/WebAssemblyInstPrinter.h"
|
||||
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
|
||||
#include "WebAssembly.h"
|
||||
#include "WebAssemblyMachineFunctionInfo.h"
|
||||
#include "llvm/ADT/SmallSet.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/CodeGen/TargetRegisterInfo.h"
|
||||
#include "llvm/MC/MCExpr.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/MC/MCInstrInfo.h"
|
||||
#include "llvm/MC/MCSubtargetInfo.h"
|
||||
#include "llvm/MC/MCSymbol.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/FormattedStream.h"
|
||||
using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "asm-printer"
|
||||
|
||||
#include "WebAssemblyGenAsmWriter.inc"
|
||||
|
||||
WebAssemblyInstPrinter::WebAssemblyInstPrinter(const MCAsmInfo &MAI,
|
||||
const MCInstrInfo &MII,
|
||||
const MCRegisterInfo &MRI)
|
||||
: MCInstPrinter(MAI, MII, MRI), ControlFlowCounter(0) {}
|
||||
|
||||
void WebAssemblyInstPrinter::printRegName(raw_ostream &OS,
|
||||
unsigned RegNo) const {
|
||||
assert(RegNo != WebAssemblyFunctionInfo::UnusedReg);
|
||||
// Note that there's an implicit get_local/set_local here!
|
||||
OS << "$" << RegNo;
|
||||
}
|
||||
|
||||
void WebAssemblyInstPrinter::printInst(const MCInst *MI, raw_ostream &OS,
|
||||
StringRef Annot,
|
||||
const MCSubtargetInfo & /*STI*/) {
|
||||
// Print the instruction (this uses the AsmStrings from the .td files).
|
||||
printInstruction(MI, OS);
|
||||
|
||||
// Print any additional variadic operands.
|
||||
const MCInstrDesc &Desc = MII.get(MI->getOpcode());
|
||||
if (Desc.isVariadic())
|
||||
for (auto i = Desc.getNumOperands(), e = MI->getNumOperands(); i < e; ++i) {
|
||||
// FIXME: For CALL_INDIRECT_VOID, don't print a leading comma, because
|
||||
// we have an extra flags operand which is not currently printed, for
|
||||
// compatiblity reasons.
|
||||
if (i != 0 &&
|
||||
(MI->getOpcode() != WebAssembly::CALL_INDIRECT_VOID ||
|
||||
i != Desc.getNumOperands()))
|
||||
OS << ", ";
|
||||
printOperand(MI, i, OS);
|
||||
}
|
||||
|
||||
// Print any added annotation.
|
||||
printAnnotation(OS, Annot);
|
||||
|
||||
if (CommentStream) {
|
||||
// Observe any effects on the control flow stack, for use in annotating
|
||||
// control flow label references.
|
||||
switch (MI->getOpcode()) {
|
||||
default:
|
||||
break;
|
||||
case WebAssembly::LOOP: {
|
||||
printAnnotation(OS, "label" + utostr(ControlFlowCounter) + ':');
|
||||
ControlFlowStack.push_back(std::make_pair(ControlFlowCounter++, true));
|
||||
break;
|
||||
}
|
||||
case WebAssembly::BLOCK:
|
||||
ControlFlowStack.push_back(std::make_pair(ControlFlowCounter++, false));
|
||||
break;
|
||||
case WebAssembly::END_LOOP:
|
||||
ControlFlowStack.pop_back();
|
||||
break;
|
||||
case WebAssembly::END_BLOCK:
|
||||
printAnnotation(
|
||||
OS, "label" + utostr(ControlFlowStack.pop_back_val().first) + ':');
|
||||
break;
|
||||
}
|
||||
|
||||
// Annotate any control flow label references.
|
||||
unsigned NumFixedOperands = Desc.NumOperands;
|
||||
SmallSet<uint64_t, 8> Printed;
|
||||
for (unsigned i = 0, e = MI->getNumOperands(); i < e; ++i) {
|
||||
if (!(i < NumFixedOperands
|
||||
? (Desc.OpInfo[i].OperandType ==
|
||||
WebAssembly::OPERAND_BASIC_BLOCK)
|
||||
: (Desc.TSFlags & WebAssemblyII::VariableOpImmediateIsLabel)))
|
||||
continue;
|
||||
uint64_t Depth = MI->getOperand(i).getImm();
|
||||
if (!Printed.insert(Depth).second)
|
||||
continue;
|
||||
const auto &Pair = ControlFlowStack.rbegin()[Depth];
|
||||
printAnnotation(OS, utostr(Depth) + ": " + (Pair.second ? "up" : "down") +
|
||||
" to label" + utostr(Pair.first));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static std::string toString(const APFloat &FP) {
|
||||
// Print NaNs with custom payloads specially.
|
||||
if (FP.isNaN() &&
|
||||
!FP.bitwiseIsEqual(APFloat::getQNaN(FP.getSemantics())) &&
|
||||
!FP.bitwiseIsEqual(
|
||||
APFloat::getQNaN(FP.getSemantics(), /*Negative=*/true))) {
|
||||
APInt AI = FP.bitcastToAPInt();
|
||||
return
|
||||
std::string(AI.isNegative() ? "-" : "") + "nan:0x" +
|
||||
utohexstr(AI.getZExtValue() &
|
||||
(AI.getBitWidth() == 32 ? INT64_C(0x007fffff) :
|
||||
INT64_C(0x000fffffffffffff)),
|
||||
/*LowerCase=*/true);
|
||||
}
|
||||
|
||||
// Use C99's hexadecimal floating-point representation.
|
||||
static const size_t BufBytes = 128;
|
||||
char buf[BufBytes];
|
||||
auto Written = FP.convertToHexString(
|
||||
buf, /*hexDigits=*/0, /*upperCase=*/false, APFloat::rmNearestTiesToEven);
|
||||
(void)Written;
|
||||
assert(Written != 0);
|
||||
assert(Written < BufBytes);
|
||||
return buf;
|
||||
}
|
||||
|
||||
void WebAssemblyInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
|
||||
raw_ostream &O) {
|
||||
const MCOperand &Op = MI->getOperand(OpNo);
|
||||
if (Op.isReg()) {
|
||||
assert((OpNo < MII.get(MI->getOpcode()).getNumOperands() ||
|
||||
MII.get(MI->getOpcode()).TSFlags == 0) &&
|
||||
"WebAssembly variable_ops register ops don't use TSFlags");
|
||||
unsigned WAReg = Op.getReg();
|
||||
if (int(WAReg) >= 0)
|
||||
printRegName(O, WAReg);
|
||||
else if (OpNo >= MII.get(MI->getOpcode()).getNumDefs())
|
||||
O << "$pop" << WebAssemblyFunctionInfo::getWARegStackId(WAReg);
|
||||
else if (WAReg != WebAssemblyFunctionInfo::UnusedReg)
|
||||
O << "$push" << WebAssemblyFunctionInfo::getWARegStackId(WAReg);
|
||||
else
|
||||
O << "$drop";
|
||||
// Add a '=' suffix if this is a def.
|
||||
if (OpNo < MII.get(MI->getOpcode()).getNumDefs())
|
||||
O << '=';
|
||||
} else if (Op.isImm()) {
|
||||
const MCInstrDesc &Desc = MII.get(MI->getOpcode());
|
||||
assert((OpNo < Desc.getNumOperands() ||
|
||||
(Desc.TSFlags & WebAssemblyII::VariableOpIsImmediate)) &&
|
||||
"WebAssemblyII::VariableOpIsImmediate should be set for "
|
||||
"variable_ops immediate ops");
|
||||
(void)Desc;
|
||||
// TODO: (MII.get(MI->getOpcode()).TSFlags &
|
||||
// WebAssemblyII::VariableOpImmediateIsLabel)
|
||||
// can tell us whether this is an immediate referencing a label in the
|
||||
// control flow stack, and it may be nice to pretty-print.
|
||||
O << Op.getImm();
|
||||
} else if (Op.isFPImm()) {
|
||||
const MCInstrDesc &Desc = MII.get(MI->getOpcode());
|
||||
assert(OpNo < Desc.getNumOperands() &&
|
||||
"Unexpected floating-point immediate as a non-fixed operand");
|
||||
assert(Desc.TSFlags == 0 &&
|
||||
"WebAssembly variable_ops floating point ops don't use TSFlags");
|
||||
const MCOperandInfo &Info = Desc.OpInfo[OpNo];
|
||||
if (Info.OperandType == WebAssembly::OPERAND_F32IMM) {
|
||||
// TODO: MC converts all floating point immediate operands to double.
|
||||
// This is fine for numeric values, but may cause NaNs to change bits.
|
||||
O << toString(APFloat(float(Op.getFPImm())));
|
||||
} else {
|
||||
assert(Info.OperandType == WebAssembly::OPERAND_F64IMM);
|
||||
O << toString(APFloat(Op.getFPImm()));
|
||||
}
|
||||
} else {
|
||||
assert((OpNo < MII.get(MI->getOpcode()).getNumOperands() ||
|
||||
(MII.get(MI->getOpcode()).TSFlags &
|
||||
WebAssemblyII::VariableOpIsImmediate)) &&
|
||||
"WebAssemblyII::VariableOpIsImmediate should be set for "
|
||||
"variable_ops expr ops");
|
||||
assert(Op.isExpr() && "unknown operand kind in printOperand");
|
||||
Op.getExpr()->print(O, &MAI);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WebAssemblyInstPrinter::printWebAssemblyP2AlignOperand(const MCInst *MI,
|
||||
unsigned OpNo,
|
||||
raw_ostream &O) {
|
||||
int64_t Imm = MI->getOperand(OpNo).getImm();
|
||||
if (Imm == WebAssembly::GetDefaultP2Align(MI->getOpcode()))
|
||||
return;
|
||||
O << ":p2align=" << Imm;
|
||||
}
|
||||
|
||||
void
|
||||
WebAssemblyInstPrinter::printWebAssemblySignatureOperand(const MCInst *MI,
|
||||
unsigned OpNo,
|
||||
raw_ostream &O) {
|
||||
int64_t Imm = MI->getOperand(OpNo).getImm();
|
||||
switch (WebAssembly::ExprType(Imm)) {
|
||||
case WebAssembly::ExprType::Void: break;
|
||||
case WebAssembly::ExprType::I32: O << "i32"; break;
|
||||
case WebAssembly::ExprType::I64: O << "i64"; break;
|
||||
case WebAssembly::ExprType::F32: O << "f32"; break;
|
||||
case WebAssembly::ExprType::F64: O << "f64"; break;
|
||||
case WebAssembly::ExprType::I8x16: O << "i8x16"; break;
|
||||
case WebAssembly::ExprType::I16x8: O << "i16x8"; break;
|
||||
case WebAssembly::ExprType::I32x4: O << "i32x4"; break;
|
||||
case WebAssembly::ExprType::F32x4: O << "f32x4"; break;
|
||||
case WebAssembly::ExprType::B8x16: O << "b8x16"; break;
|
||||
case WebAssembly::ExprType::B16x8: O << "b16x8"; break;
|
||||
case WebAssembly::ExprType::B32x4: O << "b32x4"; break;
|
||||
}
|
||||
}
|
||||
|
||||
const char *llvm::WebAssembly::TypeToString(MVT Ty) {
|
||||
switch (Ty.SimpleTy) {
|
||||
case MVT::i32:
|
||||
return "i32";
|
||||
case MVT::i64:
|
||||
return "i64";
|
||||
case MVT::f32:
|
||||
return "f32";
|
||||
case MVT::f64:
|
||||
return "f64";
|
||||
case MVT::v16i8:
|
||||
case MVT::v8i16:
|
||||
case MVT::v4i32:
|
||||
case MVT::v4f32:
|
||||
return "v128";
|
||||
default:
|
||||
llvm_unreachable("unsupported type");
|
||||
}
|
||||
}
|
||||
|
||||
const char *llvm::WebAssembly::TypeToString(wasm::ValType Type) {
|
||||
switch (Type) {
|
||||
case wasm::ValType::I32:
|
||||
return "i32";
|
||||
case wasm::ValType::I64:
|
||||
return "i64";
|
||||
case wasm::ValType::F32:
|
||||
return "f32";
|
||||
case wasm::ValType::F64:
|
||||
return "f64";
|
||||
}
|
||||
llvm_unreachable("unsupported type");
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
// WebAssemblyInstPrinter.h - Print wasm MCInst to assembly syntax -*- C++ -*-//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// \brief This class prints an WebAssembly MCInst to wasm file syntax.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_INSTPRINTER_WEBASSEMBLYINSTPRINTER_H
|
||||
#define LLVM_LIB_TARGET_WEBASSEMBLY_INSTPRINTER_WEBASSEMBLYINSTPRINTER_H
|
||||
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/BinaryFormat/Wasm.h"
|
||||
#include "llvm/CodeGen/MachineValueType.h"
|
||||
#include "llvm/MC/MCInstPrinter.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class MCSubtargetInfo;
|
||||
|
||||
class WebAssemblyInstPrinter final : public MCInstPrinter {
|
||||
uint64_t ControlFlowCounter;
|
||||
SmallVector<std::pair<uint64_t, bool>, 0> ControlFlowStack;
|
||||
|
||||
public:
|
||||
WebAssemblyInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII,
|
||||
const MCRegisterInfo &MRI);
|
||||
|
||||
void printRegName(raw_ostream &OS, unsigned RegNo) const override;
|
||||
void printInst(const MCInst *MI, raw_ostream &OS, StringRef Annot,
|
||||
const MCSubtargetInfo &STI) override;
|
||||
|
||||
// Used by tblegen code.
|
||||
void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O);
|
||||
void printWebAssemblyP2AlignOperand(const MCInst *MI, unsigned OpNo,
|
||||
raw_ostream &O);
|
||||
void printWebAssemblySignatureOperand(const MCInst *MI, unsigned OpNo,
|
||||
raw_ostream &O);
|
||||
|
||||
// Autogenerated by tblgen.
|
||||
void printInstruction(const MCInst *MI, raw_ostream &O);
|
||||
static const char *getRegisterName(unsigned RegNo);
|
||||
};
|
||||
|
||||
namespace WebAssembly {
|
||||
|
||||
const char *TypeToString(MVT Ty);
|
||||
const char *TypeToString(wasm::ValType Type);
|
||||
|
||||
} // end namespace WebAssembly
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
@ -1,33 +0,0 @@
|
||||
;===- ./lib/Target/WebAssembly/LLVMBuild.txt -------------------*- Conf -*--===;
|
||||
;
|
||||
; The LLVM Compiler Infrastructure
|
||||
;
|
||||
; This file is distributed under the University of Illinois Open Source
|
||||
; License. See LICENSE.TXT for details.
|
||||
;
|
||||
;===------------------------------------------------------------------------===;
|
||||
;
|
||||
; This is an LLVMBuild description file for the components in this subdirectory.
|
||||
;
|
||||
; For more information on the LLVMBuild system, please see:
|
||||
;
|
||||
; http://llvm.org/docs/LLVMBuild.html
|
||||
;
|
||||
;===------------------------------------------------------------------------===;
|
||||
|
||||
[common]
|
||||
subdirectories = Disassembler InstPrinter MCTargetDesc TargetInfo
|
||||
|
||||
[component_0]
|
||||
type = TargetGroup
|
||||
name = WebAssembly
|
||||
parent = Target
|
||||
has_asmprinter = 1
|
||||
has_disassembler = 1
|
||||
|
||||
[component_1]
|
||||
type = Library
|
||||
name = WebAssemblyCodeGen
|
||||
parent = WebAssembly
|
||||
required_libraries = Analysis AsmPrinter CodeGen Core MC Scalar SelectionDAG Support Target TransformUtils WebAssemblyAsmPrinter WebAssemblyDesc WebAssemblyInfo
|
||||
add_to_library_groups = WebAssembly
|
@ -1,9 +0,0 @@
|
||||
add_llvm_library(LLVMWebAssemblyDesc
|
||||
WebAssemblyAsmBackend.cpp
|
||||
WebAssemblyELFObjectWriter.cpp
|
||||
WebAssemblyMCAsmInfo.cpp
|
||||
WebAssemblyMCCodeEmitter.cpp
|
||||
WebAssemblyMCTargetDesc.cpp
|
||||
WebAssemblyTargetStreamer.cpp
|
||||
WebAssemblyWasmObjectWriter.cpp
|
||||
)
|
@ -1,23 +0,0 @@
|
||||
;===- ./lib/Target/WebAssembly/MCTargetDesc/LLVMBuild.txt ------*- Conf -*--===;
|
||||
;
|
||||
; The LLVM Compiler Infrastructure
|
||||
;
|
||||
; This file is distributed under the University of Illinois Open Source
|
||||
; License. See LICENSE.TXT for details.
|
||||
;
|
||||
;===------------------------------------------------------------------------===;
|
||||
;
|
||||
; This is an LLVMBuild description file for the components in this subdirectory.
|
||||
;
|
||||
; For more information on the LLVMBuild system, please see:
|
||||
;
|
||||
; http://llvm.org/docs/LLVMBuild.html
|
||||
;
|
||||
;===------------------------------------------------------------------------===;
|
||||
|
||||
[component_0]
|
||||
type = Library
|
||||
name = WebAssemblyDesc
|
||||
parent = WebAssembly
|
||||
required_libraries = MC Support WebAssemblyAsmPrinter WebAssemblyInfo
|
||||
add_to_library_groups = WebAssembly
|
@ -1,206 +0,0 @@
|
||||
//===-- WebAssemblyAsmBackend.cpp - WebAssembly Assembler Backend ---------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// \brief This file implements the WebAssemblyAsmBackend class.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "MCTargetDesc/WebAssemblyFixupKinds.h"
|
||||
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
|
||||
#include "llvm/MC/MCAsmBackend.h"
|
||||
#include "llvm/MC/MCAssembler.h"
|
||||
#include "llvm/MC/MCDirectives.h"
|
||||
#include "llvm/MC/MCELFObjectWriter.h"
|
||||
#include "llvm/MC/MCExpr.h"
|
||||
#include "llvm/MC/MCFixupKindInfo.h"
|
||||
#include "llvm/MC/MCObjectWriter.h"
|
||||
#include "llvm/MC/MCSubtargetInfo.h"
|
||||
#include "llvm/MC/MCSymbol.h"
|
||||
#include "llvm/MC/MCWasmObjectWriter.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
class WebAssemblyAsmBackendELF final : public MCAsmBackend {
|
||||
bool Is64Bit;
|
||||
|
||||
public:
|
||||
explicit WebAssemblyAsmBackendELF(bool Is64Bit)
|
||||
: MCAsmBackend(), Is64Bit(Is64Bit) {}
|
||||
~WebAssemblyAsmBackendELF() override {}
|
||||
|
||||
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
|
||||
const MCValue &Target, MutableArrayRef<char> Data,
|
||||
uint64_t Value, bool IsPCRel) const override;
|
||||
|
||||
std::unique_ptr<MCObjectWriter>
|
||||
createObjectWriter(raw_pwrite_stream &OS) const override;
|
||||
|
||||
// No instruction requires relaxation
|
||||
bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
|
||||
const MCRelaxableFragment *DF,
|
||||
const MCAsmLayout &Layout) const override {
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned getNumFixupKinds() const override {
|
||||
// We currently just use the generic fixups in MCFixup.h and don't have any
|
||||
// target-specific fixups.
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool mayNeedRelaxation(const MCInst &Inst) const override { return false; }
|
||||
|
||||
void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
|
||||
MCInst &Res) const override {}
|
||||
|
||||
bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override;
|
||||
};
|
||||
|
||||
class WebAssemblyAsmBackend final : public MCAsmBackend {
|
||||
bool Is64Bit;
|
||||
|
||||
public:
|
||||
explicit WebAssemblyAsmBackend(bool Is64Bit)
|
||||
: MCAsmBackend(), Is64Bit(Is64Bit) {}
|
||||
~WebAssemblyAsmBackend() override {}
|
||||
|
||||
unsigned getNumFixupKinds() const override {
|
||||
return WebAssembly::NumTargetFixupKinds;
|
||||
}
|
||||
|
||||
const MCFixupKindInfo &getFixupKindInfo(MCFixupKind Kind) const override;
|
||||
|
||||
void applyFixup(const MCAssembler &Asm, const MCFixup &Fixup,
|
||||
const MCValue &Target, MutableArrayRef<char> Data,
|
||||
uint64_t Value, bool IsPCRel) const override;
|
||||
|
||||
std::unique_ptr<MCObjectWriter>
|
||||
createObjectWriter(raw_pwrite_stream &OS) const override;
|
||||
|
||||
// No instruction requires relaxation
|
||||
bool fixupNeedsRelaxation(const MCFixup &Fixup, uint64_t Value,
|
||||
const MCRelaxableFragment *DF,
|
||||
const MCAsmLayout &Layout) const override {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool mayNeedRelaxation(const MCInst &Inst) const override { return false; }
|
||||
|
||||
void relaxInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
|
||||
MCInst &Res) const override {}
|
||||
|
||||
bool writeNopData(uint64_t Count, MCObjectWriter *OW) const override;
|
||||
};
|
||||
|
||||
bool WebAssemblyAsmBackendELF::writeNopData(uint64_t Count,
|
||||
MCObjectWriter *OW) const {
|
||||
for (uint64_t i = 0; i < Count; ++i)
|
||||
OW->write8(WebAssembly::Nop);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void WebAssemblyAsmBackendELF::applyFixup(const MCAssembler &Asm,
|
||||
const MCFixup &Fixup,
|
||||
const MCValue &Target,
|
||||
MutableArrayRef<char> Data,
|
||||
uint64_t Value, bool IsPCRel) const {
|
||||
const MCFixupKindInfo &Info = getFixupKindInfo(Fixup.getKind());
|
||||
assert(Info.Flags == 0 && "WebAssembly does not use MCFixupKindInfo flags");
|
||||
|
||||
unsigned NumBytes = alignTo(Info.TargetSize, 8) / 8;
|
||||
if (Value == 0)
|
||||
return; // Doesn't change encoding.
|
||||
|
||||
// Shift the value into position.
|
||||
Value <<= Info.TargetOffset;
|
||||
|
||||
unsigned Offset = Fixup.getOffset();
|
||||
assert(Offset + NumBytes <= Data.size() && "Invalid fixup offset!");
|
||||
|
||||
// For each byte of the fragment that the fixup touches, mask in the
|
||||
// bits from the fixup value.
|
||||
for (unsigned i = 0; i != NumBytes; ++i)
|
||||
Data[Offset + i] |= uint8_t((Value >> (i * 8)) & 0xff);
|
||||
}
|
||||
|
||||
std::unique_ptr<MCObjectWriter>
|
||||
WebAssemblyAsmBackendELF::createObjectWriter(raw_pwrite_stream &OS) const {
|
||||
return createWebAssemblyELFObjectWriter(OS, Is64Bit, 0);
|
||||
}
|
||||
|
||||
const MCFixupKindInfo &
|
||||
WebAssemblyAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
|
||||
const static MCFixupKindInfo Infos[WebAssembly::NumTargetFixupKinds] = {
|
||||
// This table *must* be in the order that the fixup_* kinds are defined in
|
||||
// WebAssemblyFixupKinds.h.
|
||||
//
|
||||
// Name Offset (bits) Size (bits) Flags
|
||||
{ "fixup_code_sleb128_i32", 0, 5*8, 0 },
|
||||
{ "fixup_code_sleb128_i64", 0, 10*8, 0 },
|
||||
{ "fixup_code_uleb128_i32", 0, 5*8, 0 },
|
||||
};
|
||||
|
||||
if (Kind < FirstTargetFixupKind)
|
||||
return MCAsmBackend::getFixupKindInfo(Kind);
|
||||
|
||||
assert(unsigned(Kind - FirstTargetFixupKind) < getNumFixupKinds() &&
|
||||
"Invalid kind!");
|
||||
return Infos[Kind - FirstTargetFixupKind];
|
||||
}
|
||||
|
||||
bool WebAssemblyAsmBackend::writeNopData(uint64_t Count,
|
||||
MCObjectWriter *OW) const {
|
||||
if (Count == 0)
|
||||
return true;
|
||||
|
||||
for (uint64_t i = 0; i < Count; ++i)
|
||||
OW->write8(WebAssembly::Nop);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void WebAssemblyAsmBackend::applyFixup(const MCAssembler &Asm,
|
||||
const MCFixup &Fixup,
|
||||
const MCValue &Target,
|
||||
MutableArrayRef<char> Data,
|
||||
uint64_t Value, bool IsPCRel) const {
|
||||
const MCFixupKindInfo &Info = getFixupKindInfo(Fixup.getKind());
|
||||
assert(Info.Flags == 0 && "WebAssembly does not use MCFixupKindInfo flags");
|
||||
|
||||
unsigned NumBytes = alignTo(Info.TargetSize, 8) / 8;
|
||||
if (Value == 0)
|
||||
return; // Doesn't change encoding.
|
||||
|
||||
// Shift the value into position.
|
||||
Value <<= Info.TargetOffset;
|
||||
|
||||
unsigned Offset = Fixup.getOffset();
|
||||
assert(Offset + NumBytes <= Data.size() && "Invalid fixup offset!");
|
||||
|
||||
// For each byte of the fragment that the fixup touches, mask in the
|
||||
// bits from the fixup value.
|
||||
for (unsigned i = 0; i != NumBytes; ++i)
|
||||
Data[Offset + i] |= uint8_t((Value >> (i * 8)) & 0xff);
|
||||
}
|
||||
|
||||
std::unique_ptr<MCObjectWriter>
|
||||
WebAssemblyAsmBackend::createObjectWriter(raw_pwrite_stream &OS) const {
|
||||
return createWebAssemblyWasmObjectWriter(OS, Is64Bit);
|
||||
}
|
||||
} // end anonymous namespace
|
||||
|
||||
MCAsmBackend *llvm::createWebAssemblyAsmBackend(const Triple &TT) {
|
||||
if (TT.isOSBinFormatELF())
|
||||
return new WebAssemblyAsmBackendELF(TT.isArch64Bit());
|
||||
return new WebAssemblyAsmBackend(TT.isArch64Bit());
|
||||
}
|
@ -1,68 +0,0 @@
|
||||
//===-- WebAssemblyELFObjectWriter.cpp - WebAssembly ELF Writer -----------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// \brief This file handles ELF-specific object emission, converting LLVM's
|
||||
/// internal fixups into the appropriate relocations.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
|
||||
#include "llvm/MC/MCELFObjectWriter.h"
|
||||
#include "llvm/MC/MCFixup.h"
|
||||
#include "llvm/MC/MCObjectWriter.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
using namespace llvm;
|
||||
|
||||
namespace {
|
||||
class WebAssemblyELFObjectWriter final : public MCELFObjectTargetWriter {
|
||||
public:
|
||||
WebAssemblyELFObjectWriter(bool Is64Bit, uint8_t OSABI);
|
||||
|
||||
protected:
|
||||
unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
|
||||
const MCFixup &Fixup, bool IsPCRel) const override;
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
WebAssemblyELFObjectWriter::WebAssemblyELFObjectWriter(bool Is64Bit,
|
||||
uint8_t OSABI)
|
||||
: MCELFObjectTargetWriter(Is64Bit, OSABI, ELF::EM_WEBASSEMBLY,
|
||||
/*HasRelocationAddend=*/false) {}
|
||||
|
||||
unsigned WebAssemblyELFObjectWriter::getRelocType(MCContext &Ctx,
|
||||
const MCValue &Target,
|
||||
const MCFixup &Fixup,
|
||||
bool IsPCRel) const {
|
||||
// WebAssembly functions are not allocated in the address space. To resolve a
|
||||
// pointer to a function, we must use a special relocation type.
|
||||
if (const MCSymbolRefExpr *SyExp =
|
||||
dyn_cast<MCSymbolRefExpr>(Fixup.getValue()))
|
||||
if (SyExp->getKind() == MCSymbolRefExpr::VK_WebAssembly_FUNCTION)
|
||||
return ELF::R_WEBASSEMBLY_FUNCTION;
|
||||
|
||||
switch (Fixup.getKind()) {
|
||||
case FK_Data_4:
|
||||
assert(!is64Bit() && "4-byte relocations only supported on wasm32");
|
||||
return ELF::R_WEBASSEMBLY_DATA;
|
||||
case FK_Data_8:
|
||||
assert(is64Bit() && "8-byte relocations only supported on wasm64");
|
||||
return ELF::R_WEBASSEMBLY_DATA;
|
||||
default:
|
||||
llvm_unreachable("unimplemented fixup kind");
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<MCObjectWriter>
|
||||
llvm::createWebAssemblyELFObjectWriter(raw_pwrite_stream &OS,
|
||||
bool Is64Bit,
|
||||
uint8_t OSABI) {
|
||||
auto MOTW = llvm::make_unique<WebAssemblyELFObjectWriter>(Is64Bit, OSABI);
|
||||
return createELFObjectWriter(std::move(MOTW), OS, /*IsLittleEndian=*/true);
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
//=- WebAssemblyFixupKinds.h - WebAssembly Specific Fixup Entries -*- C++ -*-=//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_MCTARGETDESC_WEBASSEMBLYFIXUPKINDS_H
|
||||
#define LLVM_LIB_TARGET_WEBASSEMBLY_MCTARGETDESC_WEBASSEMBLYFIXUPKINDS_H
|
||||
|
||||
#include "llvm/MC/MCFixup.h"
|
||||
|
||||
namespace llvm {
|
||||
namespace WebAssembly {
|
||||
enum Fixups {
|
||||
fixup_code_sleb128_i32 = FirstTargetFixupKind, // 32-bit signed
|
||||
fixup_code_sleb128_i64, // 64-bit signed
|
||||
fixup_code_uleb128_i32, // 32-bit unsigned
|
||||
|
||||
fixup_code_global_index, // 32-bit unsigned
|
||||
|
||||
// Marker
|
||||
LastTargetFixupKind,
|
||||
NumTargetFixupKinds = LastTargetFixupKind - FirstTargetFixupKind
|
||||
};
|
||||
} // end namespace WebAssembly
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
@ -1,83 +0,0 @@
|
||||
//===-- WebAssemblyMCAsmInfo.cpp - WebAssembly asm properties -------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// \brief This file contains the declarations of the WebAssemblyMCAsmInfo
|
||||
/// properties.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "WebAssemblyMCAsmInfo.h"
|
||||
#include "llvm/ADT/Triple.h"
|
||||
using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "wasm-mc-asm-info"
|
||||
|
||||
WebAssemblyMCAsmInfoELF::~WebAssemblyMCAsmInfoELF() {}
|
||||
|
||||
WebAssemblyMCAsmInfoELF::WebAssemblyMCAsmInfoELF(const Triple &T) {
|
||||
CodePointerSize = CalleeSaveStackSlotSize = T.isArch64Bit() ? 8 : 4;
|
||||
|
||||
// TODO: What should MaxInstLength be?
|
||||
|
||||
UseDataRegionDirectives = true;
|
||||
|
||||
// Use .skip instead of .zero because .zero is confusing when used with two
|
||||
// arguments (it doesn't actually zero things out).
|
||||
ZeroDirective = "\t.skip\t";
|
||||
|
||||
Data8bitsDirective = "\t.int8\t";
|
||||
Data16bitsDirective = "\t.int16\t";
|
||||
Data32bitsDirective = "\t.int32\t";
|
||||
Data64bitsDirective = "\t.int64\t";
|
||||
|
||||
AlignmentIsInBytes = false;
|
||||
COMMDirectiveAlignmentIsInBytes = false;
|
||||
LCOMMDirectiveAlignmentType = LCOMM::Log2Alignment;
|
||||
|
||||
SupportsDebugInformation = true;
|
||||
|
||||
// For now, WebAssembly does not support exceptions.
|
||||
ExceptionsType = ExceptionHandling::None;
|
||||
|
||||
// TODO: UseIntegratedAssembler?
|
||||
|
||||
// WebAssembly's stack is never executable.
|
||||
UsesNonexecutableStackSection = false;
|
||||
}
|
||||
|
||||
WebAssemblyMCAsmInfo::~WebAssemblyMCAsmInfo() {}
|
||||
|
||||
WebAssemblyMCAsmInfo::WebAssemblyMCAsmInfo(const Triple &T) {
|
||||
CodePointerSize = CalleeSaveStackSlotSize = T.isArch64Bit() ? 8 : 4;
|
||||
|
||||
// TODO: What should MaxInstLength be?
|
||||
|
||||
UseDataRegionDirectives = true;
|
||||
|
||||
// Use .skip instead of .zero because .zero is confusing when used with two
|
||||
// arguments (it doesn't actually zero things out).
|
||||
ZeroDirective = "\t.skip\t";
|
||||
|
||||
Data8bitsDirective = "\t.int8\t";
|
||||
Data16bitsDirective = "\t.int16\t";
|
||||
Data32bitsDirective = "\t.int32\t";
|
||||
Data64bitsDirective = "\t.int64\t";
|
||||
|
||||
AlignmentIsInBytes = false;
|
||||
COMMDirectiveAlignmentIsInBytes = false;
|
||||
LCOMMDirectiveAlignmentType = LCOMM::Log2Alignment;
|
||||
|
||||
SupportsDebugInformation = true;
|
||||
|
||||
// For now, WebAssembly does not support exceptions.
|
||||
ExceptionsType = ExceptionHandling::None;
|
||||
|
||||
// TODO: UseIntegratedAssembler?
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
//===-- WebAssemblyMCAsmInfo.h - WebAssembly asm properties -----*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// \brief This file contains the declaration of the WebAssemblyMCAsmInfo class.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_MCTARGETDESC_WEBASSEMBLYMCASMINFO_H
|
||||
#define LLVM_LIB_TARGET_WEBASSEMBLY_MCTARGETDESC_WEBASSEMBLYMCASMINFO_H
|
||||
|
||||
#include "llvm/MC/MCAsmInfoELF.h"
|
||||
#include "llvm/MC/MCAsmInfoWasm.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class Triple;
|
||||
|
||||
class WebAssemblyMCAsmInfoELF final : public MCAsmInfoELF {
|
||||
public:
|
||||
explicit WebAssemblyMCAsmInfoELF(const Triple &T);
|
||||
~WebAssemblyMCAsmInfoELF() override;
|
||||
};
|
||||
|
||||
class WebAssemblyMCAsmInfo final : public MCAsmInfoWasm {
|
||||
public:
|
||||
explicit WebAssemblyMCAsmInfo(const Triple &T);
|
||||
~WebAssemblyMCAsmInfo() override;
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
@ -1,152 +0,0 @@
|
||||
//=- WebAssemblyMCCodeEmitter.cpp - Convert WebAssembly code to machine code -//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// \brief This file implements the WebAssemblyMCCodeEmitter class.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "MCTargetDesc/WebAssemblyFixupKinds.h"
|
||||
#include "MCTargetDesc/WebAssemblyMCTargetDesc.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include "llvm/MC/MCCodeEmitter.h"
|
||||
#include "llvm/MC/MCFixup.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/MC/MCInstrInfo.h"
|
||||
#include "llvm/MC/MCRegisterInfo.h"
|
||||
#include "llvm/MC/MCSubtargetInfo.h"
|
||||
#include "llvm/MC/MCSymbol.h"
|
||||
#include "llvm/Support/EndianStream.h"
|
||||
#include "llvm/Support/LEB128.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "mccodeemitter"
|
||||
|
||||
STATISTIC(MCNumEmitted, "Number of MC instructions emitted.");
|
||||
STATISTIC(MCNumFixups, "Number of MC fixups created.");
|
||||
|
||||
namespace {
|
||||
class WebAssemblyMCCodeEmitter final : public MCCodeEmitter {
|
||||
const MCInstrInfo &MCII;
|
||||
|
||||
// Implementation generated by tablegen.
|
||||
uint64_t getBinaryCodeForInstr(const MCInst &MI,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const;
|
||||
|
||||
void encodeInstruction(const MCInst &MI, raw_ostream &OS,
|
||||
SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const override;
|
||||
|
||||
public:
|
||||
WebAssemblyMCCodeEmitter(const MCInstrInfo &mcii) : MCII(mcii) {}
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
MCCodeEmitter *llvm::createWebAssemblyMCCodeEmitter(const MCInstrInfo &MCII) {
|
||||
return new WebAssemblyMCCodeEmitter(MCII);
|
||||
}
|
||||
|
||||
void WebAssemblyMCCodeEmitter::encodeInstruction(
|
||||
const MCInst &MI, raw_ostream &OS, SmallVectorImpl<MCFixup> &Fixups,
|
||||
const MCSubtargetInfo &STI) const {
|
||||
uint64_t Start = OS.tell();
|
||||
|
||||
uint64_t Binary = getBinaryCodeForInstr(MI, Fixups, STI);
|
||||
if (Binary <= UINT8_MAX) {
|
||||
OS << uint8_t(Binary);
|
||||
} else {
|
||||
assert(Binary <= UINT16_MAX && "Several-byte opcodes not supported yet");
|
||||
OS << uint8_t(Binary >> 8)
|
||||
<< uint8_t(Binary);
|
||||
}
|
||||
|
||||
// For br_table instructions, encode the size of the table. In the MCInst,
|
||||
// there's an index operand, one operand for each table entry, and the
|
||||
// default operand.
|
||||
if (MI.getOpcode() == WebAssembly::BR_TABLE_I32 ||
|
||||
MI.getOpcode() == WebAssembly::BR_TABLE_I64)
|
||||
encodeULEB128(MI.getNumOperands() - 2, OS);
|
||||
|
||||
const MCInstrDesc &Desc = MCII.get(MI.getOpcode());
|
||||
for (unsigned i = 0, e = MI.getNumOperands(); i < e; ++i) {
|
||||
const MCOperand &MO = MI.getOperand(i);
|
||||
if (MO.isReg()) {
|
||||
/* nothing to encode */
|
||||
} else if (MO.isImm()) {
|
||||
if (i < Desc.getNumOperands()) {
|
||||
assert(Desc.TSFlags == 0 &&
|
||||
"WebAssembly non-variable_ops don't use TSFlags");
|
||||
const MCOperandInfo &Info = Desc.OpInfo[i];
|
||||
if (Info.OperandType == WebAssembly::OPERAND_I32IMM) {
|
||||
encodeSLEB128(int32_t(MO.getImm()), OS);
|
||||
} else if (Info.OperandType == WebAssembly::OPERAND_I64IMM) {
|
||||
encodeSLEB128(int64_t(MO.getImm()), OS);
|
||||
} else if (Info.OperandType == WebAssembly::OPERAND_GLOBAL) {
|
||||
llvm_unreachable("wasm globals should only be accessed symbolicly");
|
||||
} else if (Info.OperandType == WebAssembly::OPERAND_SIGNATURE) {
|
||||
encodeSLEB128(int64_t(MO.getImm()), OS);
|
||||
} else {
|
||||
encodeULEB128(uint64_t(MO.getImm()), OS);
|
||||
}
|
||||
} else {
|
||||
assert(Desc.TSFlags == (WebAssemblyII::VariableOpIsImmediate |
|
||||
WebAssemblyII::VariableOpImmediateIsLabel));
|
||||
encodeULEB128(uint64_t(MO.getImm()), OS);
|
||||
}
|
||||
} else if (MO.isFPImm()) {
|
||||
assert(i < Desc.getNumOperands() &&
|
||||
"Unexpected floating-point immediate as a non-fixed operand");
|
||||
assert(Desc.TSFlags == 0 &&
|
||||
"WebAssembly variable_ops floating point ops don't use TSFlags");
|
||||
const MCOperandInfo &Info = Desc.OpInfo[i];
|
||||
if (Info.OperandType == WebAssembly::OPERAND_F32IMM) {
|
||||
// TODO: MC converts all floating point immediate operands to double.
|
||||
// This is fine for numeric values, but may cause NaNs to change bits.
|
||||
float f = float(MO.getFPImm());
|
||||
support::endian::Writer<support::little>(OS).write<float>(f);
|
||||
} else {
|
||||
assert(Info.OperandType == WebAssembly::OPERAND_F64IMM);
|
||||
double d = MO.getFPImm();
|
||||
support::endian::Writer<support::little>(OS).write<double>(d);
|
||||
}
|
||||
} else if (MO.isExpr()) {
|
||||
const MCOperandInfo &Info = Desc.OpInfo[i];
|
||||
llvm::MCFixupKind FixupKind;
|
||||
size_t PaddedSize = 5;
|
||||
if (Info.OperandType == WebAssembly::OPERAND_I32IMM) {
|
||||
FixupKind = MCFixupKind(WebAssembly::fixup_code_sleb128_i32);
|
||||
} else if (Info.OperandType == WebAssembly::OPERAND_I64IMM) {
|
||||
FixupKind = MCFixupKind(WebAssembly::fixup_code_sleb128_i64);
|
||||
PaddedSize = 10;
|
||||
} else if (Info.OperandType == WebAssembly::OPERAND_FUNCTION32 ||
|
||||
Info.OperandType == WebAssembly::OPERAND_OFFSET32 ||
|
||||
Info.OperandType == WebAssembly::OPERAND_TYPEINDEX) {
|
||||
FixupKind = MCFixupKind(WebAssembly::fixup_code_uleb128_i32);
|
||||
} else if (Info.OperandType == WebAssembly::OPERAND_GLOBAL) {
|
||||
FixupKind = MCFixupKind(WebAssembly::fixup_code_global_index);
|
||||
} else {
|
||||
llvm_unreachable("unexpected symbolic operand kind");
|
||||
}
|
||||
Fixups.push_back(MCFixup::create(
|
||||
OS.tell() - Start, MO.getExpr(),
|
||||
FixupKind, MI.getLoc()));
|
||||
++MCNumFixups;
|
||||
encodeULEB128(0, OS, PaddedSize);
|
||||
} else {
|
||||
llvm_unreachable("unexpected operand kind");
|
||||
}
|
||||
}
|
||||
|
||||
++MCNumEmitted; // Keep track of the # of mi's emitted.
|
||||
}
|
||||
|
||||
#include "WebAssemblyGenMCCodeEmitter.inc"
|
@ -1,140 +0,0 @@
|
||||
//===-- WebAssemblyMCTargetDesc.cpp - WebAssembly Target Descriptions -----===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// \brief This file provides WebAssembly-specific target descriptions.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "WebAssemblyMCTargetDesc.h"
|
||||
#include "InstPrinter/WebAssemblyInstPrinter.h"
|
||||
#include "WebAssemblyMCAsmInfo.h"
|
||||
#include "WebAssemblyTargetStreamer.h"
|
||||
#include "llvm/MC/MCInstrInfo.h"
|
||||
#include "llvm/MC/MCRegisterInfo.h"
|
||||
#include "llvm/MC/MCSubtargetInfo.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "wasm-mc-target-desc"
|
||||
|
||||
#define GET_INSTRINFO_MC_DESC
|
||||
#include "WebAssemblyGenInstrInfo.inc"
|
||||
|
||||
#define GET_SUBTARGETINFO_MC_DESC
|
||||
#include "WebAssemblyGenSubtargetInfo.inc"
|
||||
|
||||
#define GET_REGINFO_MC_DESC
|
||||
#include "WebAssemblyGenRegisterInfo.inc"
|
||||
|
||||
static MCAsmInfo *createMCAsmInfo(const MCRegisterInfo & /*MRI*/,
|
||||
const Triple &TT) {
|
||||
if (TT.isOSBinFormatELF())
|
||||
return new WebAssemblyMCAsmInfoELF(TT);
|
||||
return new WebAssemblyMCAsmInfo(TT);
|
||||
}
|
||||
|
||||
static MCInstrInfo *createMCInstrInfo() {
|
||||
MCInstrInfo *X = new MCInstrInfo();
|
||||
InitWebAssemblyMCInstrInfo(X);
|
||||
return X;
|
||||
}
|
||||
|
||||
static MCRegisterInfo *createMCRegisterInfo(const Triple & /*T*/) {
|
||||
MCRegisterInfo *X = new MCRegisterInfo();
|
||||
InitWebAssemblyMCRegisterInfo(X, 0);
|
||||
return X;
|
||||
}
|
||||
|
||||
static MCInstPrinter *createMCInstPrinter(const Triple & /*T*/,
|
||||
unsigned SyntaxVariant,
|
||||
const MCAsmInfo &MAI,
|
||||
const MCInstrInfo &MII,
|
||||
const MCRegisterInfo &MRI) {
|
||||
assert(SyntaxVariant == 0 && "WebAssembly only has one syntax variant");
|
||||
return new WebAssemblyInstPrinter(MAI, MII, MRI);
|
||||
}
|
||||
|
||||
static MCCodeEmitter *createCodeEmitter(const MCInstrInfo &MCII,
|
||||
const MCRegisterInfo & /*MRI*/,
|
||||
MCContext &Ctx) {
|
||||
return createWebAssemblyMCCodeEmitter(MCII);
|
||||
}
|
||||
|
||||
static MCAsmBackend *createAsmBackend(const Target & /*T*/,
|
||||
const MCSubtargetInfo &STI,
|
||||
const MCRegisterInfo & /*MRI*/,
|
||||
const MCTargetOptions & /*Options*/) {
|
||||
return createWebAssemblyAsmBackend(STI.getTargetTriple());
|
||||
}
|
||||
|
||||
static MCSubtargetInfo *createMCSubtargetInfo(const Triple &TT, StringRef CPU,
|
||||
StringRef FS) {
|
||||
return createWebAssemblyMCSubtargetInfoImpl(TT, CPU, FS);
|
||||
}
|
||||
|
||||
static MCTargetStreamer *
|
||||
createObjectTargetStreamer(MCStreamer &S, const MCSubtargetInfo &STI) {
|
||||
const Triple &TT = STI.getTargetTriple();
|
||||
if (TT.isOSBinFormatELF())
|
||||
return new WebAssemblyTargetELFStreamer(S);
|
||||
|
||||
return new WebAssemblyTargetWasmStreamer(S);
|
||||
}
|
||||
|
||||
static MCTargetStreamer *createAsmTargetStreamer(MCStreamer &S,
|
||||
formatted_raw_ostream &OS,
|
||||
MCInstPrinter * /*InstPrint*/,
|
||||
bool /*isVerboseAsm*/) {
|
||||
return new WebAssemblyTargetAsmStreamer(S, OS);
|
||||
}
|
||||
|
||||
// Force static initialization.
|
||||
extern "C" void LLVMInitializeWebAssemblyTargetMC() {
|
||||
for (Target *T :
|
||||
{&getTheWebAssemblyTarget32(), &getTheWebAssemblyTarget64()}) {
|
||||
// Register the MC asm info.
|
||||
RegisterMCAsmInfoFn X(*T, createMCAsmInfo);
|
||||
|
||||
// Register the MC instruction info.
|
||||
TargetRegistry::RegisterMCInstrInfo(*T, createMCInstrInfo);
|
||||
|
||||
// Register the MC register info.
|
||||
TargetRegistry::RegisterMCRegInfo(*T, createMCRegisterInfo);
|
||||
|
||||
// Register the MCInstPrinter.
|
||||
TargetRegistry::RegisterMCInstPrinter(*T, createMCInstPrinter);
|
||||
|
||||
// Register the MC code emitter.
|
||||
TargetRegistry::RegisterMCCodeEmitter(*T, createCodeEmitter);
|
||||
|
||||
// Register the ASM Backend.
|
||||
TargetRegistry::RegisterMCAsmBackend(*T, createAsmBackend);
|
||||
|
||||
// Register the MC subtarget info.
|
||||
TargetRegistry::RegisterMCSubtargetInfo(*T, createMCSubtargetInfo);
|
||||
|
||||
// Register the object target streamer.
|
||||
TargetRegistry::RegisterObjectTargetStreamer(*T,
|
||||
createObjectTargetStreamer);
|
||||
// Register the asm target streamer.
|
||||
TargetRegistry::RegisterAsmTargetStreamer(*T, createAsmTargetStreamer);
|
||||
}
|
||||
}
|
||||
|
||||
wasm::ValType WebAssembly::toValType(const MVT &Ty) {
|
||||
switch (Ty.SimpleTy) {
|
||||
case MVT::i32: return wasm::ValType::I32;
|
||||
case MVT::i64: return wasm::ValType::I64;
|
||||
case MVT::f32: return wasm::ValType::F32;
|
||||
case MVT::f64: return wasm::ValType::F64;
|
||||
default: llvm_unreachable("unexpected type");
|
||||
}
|
||||
}
|
@ -1,185 +0,0 @@
|
||||
//==- WebAssemblyMCTargetDesc.h - WebAssembly Target Descriptions -*- C++ -*-=//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// \brief This file provides WebAssembly-specific target descriptions.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_MCTARGETDESC_WEBASSEMBLYMCTARGETDESC_H
|
||||
#define LLVM_LIB_TARGET_WEBASSEMBLY_MCTARGETDESC_WEBASSEMBLYMCTARGETDESC_H
|
||||
|
||||
#include "llvm/BinaryFormat/Wasm.h"
|
||||
#include "llvm/MC/MCInstrDesc.h"
|
||||
#include "llvm/Support/DataTypes.h"
|
||||
#include <memory>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class MCAsmBackend;
|
||||
class MCCodeEmitter;
|
||||
class MCContext;
|
||||
class MCInstrInfo;
|
||||
class MCObjectWriter;
|
||||
class MCSubtargetInfo;
|
||||
class MVT;
|
||||
class Target;
|
||||
class Triple;
|
||||
class raw_pwrite_stream;
|
||||
|
||||
Target &getTheWebAssemblyTarget32();
|
||||
Target &getTheWebAssemblyTarget64();
|
||||
|
||||
MCCodeEmitter *createWebAssemblyMCCodeEmitter(const MCInstrInfo &MCII);
|
||||
|
||||
MCAsmBackend *createWebAssemblyAsmBackend(const Triple &TT);
|
||||
|
||||
std::unique_ptr<MCObjectWriter>
|
||||
createWebAssemblyELFObjectWriter(raw_pwrite_stream &OS,
|
||||
bool Is64Bit, uint8_t OSABI);
|
||||
|
||||
std::unique_ptr<MCObjectWriter>
|
||||
createWebAssemblyWasmObjectWriter(raw_pwrite_stream &OS,
|
||||
bool Is64Bit);
|
||||
|
||||
namespace WebAssembly {
|
||||
enum OperandType {
|
||||
/// Basic block label in a branch construct.
|
||||
OPERAND_BASIC_BLOCK = MCOI::OPERAND_FIRST_TARGET,
|
||||
/// Local index.
|
||||
OPERAND_LOCAL,
|
||||
/// Global index.
|
||||
OPERAND_GLOBAL,
|
||||
/// 32-bit integer immediates.
|
||||
OPERAND_I32IMM,
|
||||
/// 64-bit integer immediates.
|
||||
OPERAND_I64IMM,
|
||||
/// 32-bit floating-point immediates.
|
||||
OPERAND_F32IMM,
|
||||
/// 64-bit floating-point immediates.
|
||||
OPERAND_F64IMM,
|
||||
/// 32-bit unsigned function indices.
|
||||
OPERAND_FUNCTION32,
|
||||
/// 32-bit unsigned memory offsets.
|
||||
OPERAND_OFFSET32,
|
||||
/// p2align immediate for load and store address alignment.
|
||||
OPERAND_P2ALIGN,
|
||||
/// signature immediate for block/loop.
|
||||
OPERAND_SIGNATURE,
|
||||
/// type signature immediate for call_indirect.
|
||||
OPERAND_TYPEINDEX,
|
||||
};
|
||||
} // end namespace WebAssembly
|
||||
|
||||
namespace WebAssemblyII {
|
||||
enum {
|
||||
// For variadic instructions, this flag indicates whether an operand
|
||||
// in the variable_ops range is an immediate value.
|
||||
VariableOpIsImmediate = (1 << 0),
|
||||
// For immediate values in the variable_ops range, this flag indicates
|
||||
// whether the value represents a control-flow label.
|
||||
VariableOpImmediateIsLabel = (1 << 1)
|
||||
};
|
||||
} // end namespace WebAssemblyII
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
// Defines symbolic names for WebAssembly registers. This defines a mapping from
|
||||
// register name to register number.
|
||||
//
|
||||
#define GET_REGINFO_ENUM
|
||||
#include "WebAssemblyGenRegisterInfo.inc"
|
||||
|
||||
// Defines symbolic names for the WebAssembly instructions.
|
||||
//
|
||||
#define GET_INSTRINFO_ENUM
|
||||
#include "WebAssemblyGenInstrInfo.inc"
|
||||
|
||||
#define GET_SUBTARGETINFO_ENUM
|
||||
#include "WebAssemblyGenSubtargetInfo.inc"
|
||||
|
||||
namespace llvm {
|
||||
namespace WebAssembly {
|
||||
|
||||
/// Return the default p2align value for a load or store with the given opcode.
|
||||
inline unsigned GetDefaultP2Align(unsigned Opcode) {
|
||||
switch (Opcode) {
|
||||
case WebAssembly::LOAD8_S_I32:
|
||||
case WebAssembly::LOAD8_U_I32:
|
||||
case WebAssembly::LOAD8_S_I64:
|
||||
case WebAssembly::LOAD8_U_I64:
|
||||
case WebAssembly::ATOMIC_LOAD8_U_I32:
|
||||
case WebAssembly::ATOMIC_LOAD8_U_I64:
|
||||
case WebAssembly::STORE8_I32:
|
||||
case WebAssembly::STORE8_I64:
|
||||
return 0;
|
||||
case WebAssembly::LOAD16_S_I32:
|
||||
case WebAssembly::LOAD16_U_I32:
|
||||
case WebAssembly::LOAD16_S_I64:
|
||||
case WebAssembly::LOAD16_U_I64:
|
||||
case WebAssembly::ATOMIC_LOAD16_U_I32:
|
||||
case WebAssembly::ATOMIC_LOAD16_U_I64:
|
||||
case WebAssembly::STORE16_I32:
|
||||
case WebAssembly::STORE16_I64:
|
||||
return 1;
|
||||
case WebAssembly::LOAD_I32:
|
||||
case WebAssembly::LOAD_F32:
|
||||
case WebAssembly::STORE_I32:
|
||||
case WebAssembly::STORE_F32:
|
||||
case WebAssembly::LOAD32_S_I64:
|
||||
case WebAssembly::LOAD32_U_I64:
|
||||
case WebAssembly::STORE32_I64:
|
||||
case WebAssembly::ATOMIC_LOAD_I32:
|
||||
case WebAssembly::ATOMIC_LOAD32_U_I64:
|
||||
return 2;
|
||||
case WebAssembly::LOAD_I64:
|
||||
case WebAssembly::LOAD_F64:
|
||||
case WebAssembly::STORE_I64:
|
||||
case WebAssembly::STORE_F64:
|
||||
case WebAssembly::ATOMIC_LOAD_I64:
|
||||
return 3;
|
||||
default:
|
||||
llvm_unreachable("Only loads and stores have p2align values");
|
||||
}
|
||||
}
|
||||
|
||||
/// The operand number of the load or store address in load/store instructions.
|
||||
static const unsigned LoadAddressOperandNo = 3;
|
||||
static const unsigned StoreAddressOperandNo = 2;
|
||||
|
||||
/// The operand number of the load or store p2align in load/store instructions.
|
||||
static const unsigned LoadP2AlignOperandNo = 1;
|
||||
static const unsigned StoreP2AlignOperandNo = 0;
|
||||
|
||||
/// This is used to indicate block signatures.
|
||||
enum class ExprType {
|
||||
Void = -0x40,
|
||||
I32 = -0x01,
|
||||
I64 = -0x02,
|
||||
F32 = -0x03,
|
||||
F64 = -0x04,
|
||||
I8x16 = -0x05,
|
||||
I16x8 = -0x06,
|
||||
I32x4 = -0x07,
|
||||
F32x4 = -0x08,
|
||||
B8x16 = -0x09,
|
||||
B16x8 = -0x0a,
|
||||
B32x4 = -0x0b
|
||||
};
|
||||
|
||||
/// Instruction opcodes emitted via means other than CodeGen.
|
||||
static const unsigned Nop = 0x01;
|
||||
static const unsigned End = 0x0b;
|
||||
|
||||
wasm::ValType toValType(const MVT &Ty);
|
||||
|
||||
} // end namespace WebAssembly
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
@ -1,264 +0,0 @@
|
||||
//==-- WebAssemblyTargetStreamer.cpp - WebAssembly Target Streamer Methods --=//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// \brief This file defines WebAssembly-specific target streamer classes.
|
||||
/// These are for implementing support for target-specific assembly directives.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "WebAssemblyTargetStreamer.h"
|
||||
#include "InstPrinter/WebAssemblyInstPrinter.h"
|
||||
#include "WebAssemblyMCTargetDesc.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCSectionELF.h"
|
||||
#include "llvm/MC/MCSectionWasm.h"
|
||||
#include "llvm/MC/MCSubtargetInfo.h"
|
||||
#include "llvm/MC/MCSymbolELF.h"
|
||||
#include "llvm/MC/MCSymbolWasm.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/FormattedStream.h"
|
||||
using namespace llvm;
|
||||
|
||||
WebAssemblyTargetStreamer::WebAssemblyTargetStreamer(MCStreamer &S)
|
||||
: MCTargetStreamer(S) {}
|
||||
|
||||
void WebAssemblyTargetStreamer::emitValueType(wasm::ValType Type) {
|
||||
Streamer.EmitSLEB128IntValue(int32_t(Type));
|
||||
}
|
||||
|
||||
WebAssemblyTargetAsmStreamer::WebAssemblyTargetAsmStreamer(
|
||||
MCStreamer &S, formatted_raw_ostream &OS)
|
||||
: WebAssemblyTargetStreamer(S), OS(OS) {}
|
||||
|
||||
WebAssemblyTargetELFStreamer::WebAssemblyTargetELFStreamer(MCStreamer &S)
|
||||
: WebAssemblyTargetStreamer(S) {}
|
||||
|
||||
WebAssemblyTargetWasmStreamer::WebAssemblyTargetWasmStreamer(MCStreamer &S)
|
||||
: WebAssemblyTargetStreamer(S) {}
|
||||
|
||||
static void PrintTypes(formatted_raw_ostream &OS, ArrayRef<MVT> Types) {
|
||||
bool First = true;
|
||||
for (MVT Type : Types) {
|
||||
if (First)
|
||||
First = false;
|
||||
else
|
||||
OS << ", ";
|
||||
OS << WebAssembly::TypeToString(Type);
|
||||
}
|
||||
OS << '\n';
|
||||
}
|
||||
|
||||
void WebAssemblyTargetAsmStreamer::emitParam(MCSymbol *Symbol,
|
||||
ArrayRef<MVT> Types) {
|
||||
if (!Types.empty()) {
|
||||
OS << "\t.param \t";
|
||||
|
||||
// FIXME: Currently this applies to the "current" function; it may
|
||||
// be cleaner to specify an explicit symbol as part of the directive.
|
||||
|
||||
PrintTypes(OS, Types);
|
||||
}
|
||||
}
|
||||
|
||||
void WebAssemblyTargetAsmStreamer::emitResult(MCSymbol *Symbol,
|
||||
ArrayRef<MVT> Types) {
|
||||
if (!Types.empty()) {
|
||||
OS << "\t.result \t";
|
||||
|
||||
// FIXME: Currently this applies to the "current" function; it may
|
||||
// be cleaner to specify an explicit symbol as part of the directive.
|
||||
|
||||
PrintTypes(OS, Types);
|
||||
}
|
||||
}
|
||||
|
||||
void WebAssemblyTargetAsmStreamer::emitLocal(ArrayRef<MVT> Types) {
|
||||
if (!Types.empty()) {
|
||||
OS << "\t.local \t";
|
||||
PrintTypes(OS, Types);
|
||||
}
|
||||
}
|
||||
|
||||
void WebAssemblyTargetAsmStreamer::emitGlobal(
|
||||
ArrayRef<wasm::Global> Globals) {
|
||||
if (!Globals.empty()) {
|
||||
OS << "\t.globalvar \t";
|
||||
|
||||
bool First = true;
|
||||
for (const wasm::Global &G : Globals) {
|
||||
if (First)
|
||||
First = false;
|
||||
else
|
||||
OS << ", ";
|
||||
OS << WebAssembly::TypeToString(G.Type);
|
||||
if (!G.InitialModule.empty())
|
||||
OS << '=' << G.InitialModule << ':' << G.InitialName;
|
||||
else
|
||||
OS << '=' << G.InitialValue;
|
||||
}
|
||||
OS << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
void WebAssemblyTargetAsmStreamer::emitEndFunc() { OS << "\t.endfunc\n"; }
|
||||
|
||||
void WebAssemblyTargetAsmStreamer::emitIndirectFunctionType(
|
||||
MCSymbol *Symbol, SmallVectorImpl<MVT> &Params, SmallVectorImpl<MVT> &Results) {
|
||||
OS << "\t.functype\t" << Symbol->getName();
|
||||
if (Results.empty())
|
||||
OS << ", void";
|
||||
else {
|
||||
assert(Results.size() == 1);
|
||||
OS << ", " << WebAssembly::TypeToString(Results.front());
|
||||
}
|
||||
for (auto Ty : Params)
|
||||
OS << ", " << WebAssembly::TypeToString(Ty);
|
||||
OS << '\n';
|
||||
}
|
||||
|
||||
void WebAssemblyTargetAsmStreamer::emitGlobalImport(StringRef name) {
|
||||
OS << "\t.import_global\t" << name << '\n';
|
||||
}
|
||||
|
||||
void WebAssemblyTargetAsmStreamer::emitIndIdx(const MCExpr *Value) {
|
||||
OS << "\t.indidx \t" << *Value << '\n';
|
||||
}
|
||||
|
||||
void WebAssemblyTargetELFStreamer::emitParam(MCSymbol *Symbol,
|
||||
ArrayRef<MVT> Types) {
|
||||
// Nothing to emit; params are declared as part of the function signature.
|
||||
}
|
||||
|
||||
void WebAssemblyTargetELFStreamer::emitResult(MCSymbol *Symbol,
|
||||
ArrayRef<MVT> Types) {
|
||||
// Nothing to emit; results are declared as part of the function signature.
|
||||
}
|
||||
|
||||
void WebAssemblyTargetELFStreamer::emitLocal(ArrayRef<MVT> Types) {
|
||||
Streamer.EmitULEB128IntValue(Types.size());
|
||||
for (MVT Type : Types)
|
||||
emitValueType(WebAssembly::toValType(Type));
|
||||
}
|
||||
|
||||
void WebAssemblyTargetELFStreamer::emitGlobal(
|
||||
ArrayRef<wasm::Global> Globals) {
|
||||
llvm_unreachable(".globalvar encoding not yet implemented");
|
||||
}
|
||||
|
||||
void WebAssemblyTargetELFStreamer::emitEndFunc() {
|
||||
Streamer.EmitIntValue(WebAssembly::End, 1);
|
||||
}
|
||||
|
||||
void WebAssemblyTargetELFStreamer::emitIndIdx(const MCExpr *Value) {
|
||||
llvm_unreachable(".indidx encoding not yet implemented");
|
||||
}
|
||||
|
||||
void WebAssemblyTargetELFStreamer::emitIndirectFunctionType(
|
||||
MCSymbol *Symbol, SmallVectorImpl<MVT> &Params, SmallVectorImpl<MVT> &Results) {
|
||||
// Nothing to emit here. TODO: Re-design how linking works and re-evaluate
|
||||
// whether it's necessary for .o files to declare indirect function types.
|
||||
}
|
||||
|
||||
void WebAssemblyTargetELFStreamer::emitGlobalImport(StringRef name) {
|
||||
}
|
||||
|
||||
void WebAssemblyTargetWasmStreamer::emitParam(MCSymbol *Symbol,
|
||||
ArrayRef<MVT> Types) {
|
||||
SmallVector<wasm::ValType, 4> Params;
|
||||
for (MVT Ty : Types)
|
||||
Params.push_back(WebAssembly::toValType(Ty));
|
||||
|
||||
cast<MCSymbolWasm>(Symbol)->setParams(std::move(Params));
|
||||
}
|
||||
|
||||
void WebAssemblyTargetWasmStreamer::emitResult(MCSymbol *Symbol,
|
||||
ArrayRef<MVT> Types) {
|
||||
SmallVector<wasm::ValType, 4> Returns;
|
||||
for (MVT Ty : Types)
|
||||
Returns.push_back(WebAssembly::toValType(Ty));
|
||||
|
||||
cast<MCSymbolWasm>(Symbol)->setReturns(std::move(Returns));
|
||||
}
|
||||
|
||||
void WebAssemblyTargetWasmStreamer::emitLocal(ArrayRef<MVT> Types) {
|
||||
SmallVector<std::pair<MVT, uint32_t>, 4> Grouped;
|
||||
for (MVT Type : Types) {
|
||||
if (Grouped.empty() || Grouped.back().first != Type)
|
||||
Grouped.push_back(std::make_pair(Type, 1));
|
||||
else
|
||||
++Grouped.back().second;
|
||||
}
|
||||
|
||||
Streamer.EmitULEB128IntValue(Grouped.size());
|
||||
for (auto Pair : Grouped) {
|
||||
Streamer.EmitULEB128IntValue(Pair.second);
|
||||
emitValueType(WebAssembly::toValType(Pair.first));
|
||||
}
|
||||
}
|
||||
|
||||
void WebAssemblyTargetWasmStreamer::emitGlobal(
|
||||
ArrayRef<wasm::Global> Globals) {
|
||||
// Encode the globals use by the funciton into the special .global_variables
|
||||
// section. This will later be decoded and turned into contents for the
|
||||
// Globals Section.
|
||||
Streamer.PushSection();
|
||||
Streamer.SwitchSection(Streamer.getContext().getWasmSection(
|
||||
".global_variables", SectionKind::getMetadata()));
|
||||
for (const wasm::Global &G : Globals) {
|
||||
Streamer.EmitIntValue(int32_t(G.Type), 1);
|
||||
Streamer.EmitIntValue(G.Mutable, 1);
|
||||
if (G.InitialModule.empty()) {
|
||||
Streamer.EmitIntValue(0, 1); // indicate that we have an int value
|
||||
Streamer.EmitSLEB128IntValue(0);
|
||||
} else {
|
||||
Streamer.EmitIntValue(1, 1); // indicate that we have a module import
|
||||
Streamer.EmitBytes(G.InitialModule);
|
||||
Streamer.EmitIntValue(0, 1); // nul-terminate
|
||||
Streamer.EmitBytes(G.InitialName);
|
||||
Streamer.EmitIntValue(0, 1); // nul-terminate
|
||||
}
|
||||
}
|
||||
Streamer.PopSection();
|
||||
}
|
||||
|
||||
void WebAssemblyTargetWasmStreamer::emitEndFunc() {
|
||||
llvm_unreachable(".end_func is not needed for direct wasm output");
|
||||
}
|
||||
|
||||
void WebAssemblyTargetWasmStreamer::emitIndIdx(const MCExpr *Value) {
|
||||
llvm_unreachable(".indidx encoding not yet implemented");
|
||||
}
|
||||
|
||||
void WebAssemblyTargetWasmStreamer::emitIndirectFunctionType(
|
||||
MCSymbol *Symbol, SmallVectorImpl<MVT> &Params,
|
||||
SmallVectorImpl<MVT> &Results) {
|
||||
MCSymbolWasm *WasmSym = cast<MCSymbolWasm>(Symbol);
|
||||
if (WasmSym->isFunction()) {
|
||||
// Symbol already has its arguments and result set.
|
||||
return;
|
||||
}
|
||||
|
||||
SmallVector<wasm::ValType, 4> ValParams;
|
||||
for (MVT Ty : Params)
|
||||
ValParams.push_back(WebAssembly::toValType(Ty));
|
||||
|
||||
SmallVector<wasm::ValType, 1> ValResults;
|
||||
for (MVT Ty : Results)
|
||||
ValResults.push_back(WebAssembly::toValType(Ty));
|
||||
|
||||
WasmSym->setParams(std::move(ValParams));
|
||||
WasmSym->setReturns(std::move(ValResults));
|
||||
WasmSym->setIsFunction(true);
|
||||
}
|
||||
|
||||
void WebAssemblyTargetWasmStreamer::emitGlobalImport(StringRef name) {
|
||||
llvm_unreachable(".global_import is not needed for direct wasm output");
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user