mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-10-19 02:52:53 +02:00
[WebAssembly] Use TSFlags instead of keeping a list of special-case opcodes.
llvm-svn: 257433
This commit is contained in:
parent
049c623237
commit
77b2aec88f
@ -82,6 +82,9 @@ 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);
|
||||
@ -95,19 +98,28 @@ void WebAssemblyInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
|
||||
if (OpNo < MII.get(MI->getOpcode()).getNumDefs())
|
||||
O << '=';
|
||||
} else if (Op.isImm()) {
|
||||
switch (MI->getOpcode()) {
|
||||
case WebAssembly::PARAM:
|
||||
case WebAssembly::RESULT:
|
||||
case WebAssembly::LOCAL:
|
||||
assert((OpNo < MII.get(MI->getOpcode()).getNumOperands() ||
|
||||
(MII.get(MI->getOpcode()).TSFlags &
|
||||
WebAssemblyII::VariableOpIsImmediate)) &&
|
||||
"WebAssemblyII::VariableOpIsImmediate should be set for "
|
||||
"variable_ops immediate ops");
|
||||
if (MII.get(MI->getOpcode()).TSFlags &
|
||||
WebAssemblyII::VariableOpImmediateIsType)
|
||||
// The immediates represent types.
|
||||
O << WebAssembly::TypeToString(MVT::SimpleValueType(Op.getImm()));
|
||||
break;
|
||||
default:
|
||||
else
|
||||
O << Op.getImm();
|
||||
break;
|
||||
}
|
||||
} else if (Op.isFPImm())
|
||||
} else if (Op.isFPImm()) {
|
||||
assert((OpNo < MII.get(MI->getOpcode()).getNumOperands() ||
|
||||
MII.get(MI->getOpcode()).TSFlags == 0) &&
|
||||
"WebAssembly variable_ops floating point ops don't use TSFlags");
|
||||
O << toString(APFloat(Op.getFPImm()));
|
||||
else {
|
||||
} 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);
|
||||
}
|
||||
|
@ -56,4 +56,15 @@ MCObjectWriter *createWebAssemblyELFObjectWriter(raw_pwrite_stream &OS,
|
||||
#define GET_SUBTARGETINFO_ENUM
|
||||
#include "WebAssemblyGenSubtargetInfo.inc"
|
||||
|
||||
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 type.
|
||||
VariableOpImmediateIsType = (1 << 1),
|
||||
};
|
||||
} // end namespace WebAssemblyII
|
||||
|
||||
#endif
|
||||
|
@ -41,13 +41,18 @@ let Defs = [ARGUMENTS] in {
|
||||
// TODO: SelectionDAG's lowering insists on using a pointer as the index for
|
||||
// jump tables, so in practice we don't ever use TABLESWITCH_I64 in wasm32 mode
|
||||
// currently.
|
||||
// Set TSFlags{0} to 1 to indicate that the variable_ops are immediates.
|
||||
let isTerminator = 1, hasCtrlDep = 1, isBarrier = 1 in {
|
||||
def TABLESWITCH_I32 : I<(outs), (ins I32:$index, bb_op:$default, variable_ops),
|
||||
[(WebAssemblytableswitch I32:$index, bb:$default)],
|
||||
"tableswitch\t$index, $default">;
|
||||
"tableswitch\t$index, $default"> {
|
||||
let TSFlags{0} = 1;
|
||||
}
|
||||
def TABLESWITCH_I64 : I<(outs), (ins I64:$index, bb_op:$default, variable_ops),
|
||||
[(WebAssemblytableswitch I64:$index, bb:$default)],
|
||||
"tableswitch\t$index, $default">;
|
||||
"tableswitch\t$index, $default"> {
|
||||
let TSFlags{0} = 1;
|
||||
}
|
||||
} // isTerminator = 1, hasCtrlDep = 1, isBarrier = 1
|
||||
|
||||
// Placemarkers to indicate the start of a block or loop scope. These
|
||||
|
@ -138,9 +138,20 @@ def : Pat<(i32 (WebAssemblywrapper texternalsym:$addr)),
|
||||
let Defs = [ARGUMENTS] in {
|
||||
|
||||
// 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">;
|
||||
// Set TSFlags{0} to 1 to indicate that the variable_ops are immediates.
|
||||
// Set TSFlags{1} to 1 to indicate that the immediates represent types.
|
||||
def PARAM : I<(outs), (ins variable_ops), [], ".param \t"> {
|
||||
let TSFlags{0} = 1;
|
||||
let TSFlags{1} = 1;
|
||||
}
|
||||
def RESULT : I<(outs), (ins variable_ops), [], ".result \t"> {
|
||||
let TSFlags{0} = 1;
|
||||
let TSFlags{1} = 1;
|
||||
}
|
||||
def LOCAL : I<(outs), (ins variable_ops), [], ".local \t"> {
|
||||
let TSFlags{0} = 1;
|
||||
let TSFlags{1} = 1;
|
||||
}
|
||||
|
||||
} // Defs = [ARGUMENTS]
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user