1
0
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:
Dan Gohman 2016-01-12 01:45:12 +00:00
parent 049c623237
commit 77b2aec88f
4 changed files with 54 additions and 15 deletions

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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]