LLVM: lib/Target/WebAssembly/MCTargetDesc/WebAssemblyInstPrinter.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

30using namespace llvm;

31

32#define DEBUG_TYPE "asm-printer"

33

34#include "WebAssemblyGenAsmWriter.inc"

35

40

43

44 OS << "$" << Reg.id();

45}

46

51 switch (MI->getOpcode()) {

52 case WebAssembly::CALL_INDIRECT_S:

53 case WebAssembly::RET_CALL_INDIRECT_S: {

54

55

56

57

58

59 OS << "\t";

61 OS << " ";

62

63 assert(MI->getNumOperands() == 2);

64 const unsigned TypeOperand = 0;

65 const unsigned TableOperand = 1;

66 if (MI->getOperand(TableOperand).isExpr()) {

68 OS << ", ";

69 } else {

70 assert(MI->getOperand(TableOperand).getImm() == 0);

71 }

73 break;

74 }

75 default:

76

78 break;

79 }

80

81

83 if (Desc.isVariadic()) {

84 if ((Desc.getNumOperands() == 0 && MI->getNumOperands() > 0) ||

85 Desc.variadicOpsAreDefs())

86 OS << "\t";

87 unsigned Start = Desc.getNumOperands();

88 unsigned NumVariadicDefs = 0;

89 if (Desc.variadicOpsAreDefs()) {

90

91 NumVariadicDefs = MI->getOperand(0).getImm();

92 Start = 1;

93 }

94 bool NeedsComma = Desc.getNumOperands() > 0 && Desc.variadicOpsAreDefs();

95 for (auto I = Start, E = MI->getNumOperands(); I < E; ++I) {

96 if (MI->getOpcode() == WebAssembly::CALL_INDIRECT &&

97 I - Start == NumVariadicDefs) {

98

99 ++I;

100 continue;

101 }

102 if (NeedsComma)

103 OS << ", ";

105 NeedsComma = true;

106 }

107 }

108

109

111

112 auto PrintBranchAnnotation = [&](const MCOperand &Op,

115 if (!Printed.insert(Depth).second)

116 return;

117 if (Depth >= ControlFlowStack.size()) {

119 } else {

120 const auto &Pair = ControlFlowStack.rbegin()[Depth];

122 " to label" + utostr(Pair.first));

123 }

124 };

125

127

128

129 unsigned Opc = MI->getOpcode();

130 switch (Opc) {

131 default:

132 break;

133

134 case WebAssembly::LOOP:

135 case WebAssembly::LOOP_S:

137 ControlFlowStack.push_back(std::make_pair(ControlFlowCounter++, true));

138 return;

139

140 case WebAssembly::BLOCK:

141 case WebAssembly::BLOCK_S:

142 ControlFlowStack.push_back(std::make_pair(ControlFlowCounter++, false));

143 return;

144

145 case WebAssembly::TRY:

146 case WebAssembly::TRY_S:

147 ControlFlowStack.push_back(std::make_pair(ControlFlowCounter, false));

148 TryStack.push_back(ControlFlowCounter++);

149 EHInstStack.push_back(TRY);

150 return;

151

152 case WebAssembly::TRY_TABLE:

153 case WebAssembly::TRY_TABLE_S: {

155 unsigned OpIdx = 1;

157 unsigned NumCatches = Op.getImm();

158 for (unsigned I = 0; I < NumCatches; I++) {

159 int64_t CatchOpcode = MI->getOperand(OpIdx++).getImm();

162 OpIdx++;

163 PrintBranchAnnotation(MI->getOperand(OpIdx++), Printed);

164 }

165 ControlFlowStack.push_back(std::make_pair(ControlFlowCounter++, false));

166 return;

167 }

168

169 case WebAssembly::END_LOOP:

170 case WebAssembly::END_LOOP_S:

171 if (ControlFlowStack.empty()) {

173 } else {

174 ControlFlowStack.pop_back();

175 }

176 return;

177

178 case WebAssembly::END_BLOCK:

179 case WebAssembly::END_BLOCK_S:

180 case WebAssembly::END_TRY_TABLE:

181 case WebAssembly::END_TRY_TABLE_S:

182 if (ControlFlowStack.empty()) {

184 } else {

186 OS, "label" + utostr(ControlFlowStack.pop_back_val().first) + ':');

187 }

188 return;

189

190 case WebAssembly::END_TRY:

191 case WebAssembly::END_TRY_S:

192 if (ControlFlowStack.empty() || EHInstStack.empty()) {

194 } else {

196 OS, "label" + utostr(ControlFlowStack.pop_back_val().first) + ':');

197 EHInstStack.pop_back();

198 }

199 return;

200

201 case WebAssembly::CATCH_LEGACY:

202 case WebAssembly::CATCH_LEGACY_S:

203 case WebAssembly::CATCH_ALL_LEGACY:

204 case WebAssembly::CATCH_ALL_LEGACY_S:

205

206

207 if (EHInstStack.empty()) {

209 } else if (EHInstStack.back() == CATCH_ALL_LEGACY) {

210 printAnnotation(OS, "catch/catch_all cannot occur after catch_all");

211 } else if (EHInstStack.back() == TRY) {

212 if (TryStack.empty()) {

214 } else {

216 }

217 EHInstStack.pop_back();

218 if (Opc == WebAssembly::CATCH_LEGACY ||

219 Opc == WebAssembly::CATCH_LEGACY_S) {

220 EHInstStack.push_back(CATCH_LEGACY);

221 } else {

222 EHInstStack.push_back(CATCH_ALL_LEGACY);

223 }

224 }

225 return;

226

227 case WebAssembly::RETHROW:

228 case WebAssembly::RETHROW_S:

229

230

231 if (TryStack.empty()) {

233 } else {

235 }

236 return;

237

238 case WebAssembly::DELEGATE:

239 case WebAssembly::DELEGATE_S:

240 if (ControlFlowStack.empty() || TryStack.empty() || EHInstStack.empty()) {

242 } else {

243

244

245

246

247 assert(ControlFlowStack.back().first == TryStack.back());

248 std::string Label = "label/catch" +

249 utostr(ControlFlowStack.pop_back_val().first) +

250 ": ";

251 TryStack.pop_back();

252 EHInstStack.pop_back();

254 if (Depth >= ControlFlowStack.size()) {

255 Label += "to caller";

256 } else {

257 const auto &Pair = ControlFlowStack.rbegin()[Depth];

258 if (Pair.second)

260 else

261 Label += "down to catch" + utostr(Pair.first);

262 }

264 }

265 return;

266 }

267

268

269

270 unsigned NumFixedOperands = Desc.NumOperands;

272 for (unsigned I = 0, E = MI->getNumOperands(); I < E; ++I) {

273

274 if (I < NumFixedOperands) {

275

277 continue;

278 } else {

279

280

281

282

283 if (MI->getOperand(I).isImm())

284 continue;

285 }

286 PrintBranchAnnotation(MI->getOperand(I), Printed);

287 }

288 }

289}

290

292

294 FP.bitwiseIsEqual(

296 APInt AI = FP.bitcastToAPInt();

297 return std::string(AI.isNegative() ? "-" : "") + "nan:0x" +

299 (AI.getBitWidth() == 32 ? INT64_C(0x007fffff)

300 : INT64_C(0x000fffffffffffff)),

301 true);

302 }

303

304

305 static const size_t BufBytes = 128;

306 char Buf[BufBytes];

307 auto Written = FP.convertToHexString(

309 (void)Written;

310 assert(Written != 0);

311 assert(Written < BufBytes);

312 return Buf;

313}

314

318 if (Op.isReg()) {

321 if (int(WAReg.id()) >= 0)

323 else if (OpNo >= Desc.getNumDefs() && !IsVariadicDef)

327 else

328 O << "$drop";

329

330 if (OpNo < MII.get(MI->getOpcode()).getNumDefs() || IsVariadicDef)

331 O << '=';

332 } else if (Op.isImm()) {

333 O << Op.getImm();

334 } else if (Op.isSFPImm()) {

336 } else if (Op.isDFPImm()) {

338 } else {

339 assert(Op.isExpr() && "unknown operand kind in printOperand");

340

341

342

345 auto &Sym = static_cast<const MCSymbolWasm &>(SRE->getSymbol());

347 } else {

348 MAI.printExpr(O, *Op.getExpr());

349 }

350 }

351}

352

355 O << "{";

356 for (unsigned I = OpNo, E = MI->getNumOperands(); I != E; ++I) {

357 if (I != OpNo)

358 O << ", ";

359 O << MI->getOperand(I).getImm();

360 }

361 O << "}";

362}

363

365 unsigned OpNo,

367 int64_t Imm = MI->getOperand(OpNo).getImm();

369 return;

370 O << ":p2align=" << Imm;

371}

372

374 unsigned OpNo,

377 if (Op.isImm()) {

378 auto Imm = static_cast<unsigned>(Op.getImm());

381 } else {

383 auto *Sym = static_cast<const MCSymbolWasm *>(&Expr->getSymbol());

384 if (Sym->getSignature()) {

386 } else {

387

388 O << "unknown_type";

389 }

390 }

391}

392

395 unsigned OpIdx = OpNo;

397 unsigned NumCatches = Op.getImm();

398

399 auto PrintTagOp = [&](const MCOperand &Op) {

401 const MCSymbol *TagSym = nullptr;

402 if (Op.isExpr()) {

405 O << TagSym->getName() << " ";

406 } else {

407

408

409 O << Op.getImm() << " ";

410 }

411 };

412

413 for (unsigned I = 0; I < NumCatches; I++) {

415 O << "(";

416 switch (Op.getImm()) {

418 O << "catch ";

419 PrintTagOp(MI->getOperand(OpIdx++));

420 break;

422 O << "catch_ref ";

423 PrintTagOp(MI->getOperand(OpIdx++));

424 break;

426 O << "catch_all ";

427 break;

429 O << "catch_all_ref ";

430 break;

431 }

432 O << MI->getOperand(OpIdx++).getImm();

433 O << ")";

434 if (I < NumCatches - 1)

435 O << " ";

436 }

437}

assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")

This file declares a class to represent arbitrary precision floating point values and provide a varie...

MachineInstr unsigned OpIdx

This file defines the SmallSet class.

This class prints an WebAssembly MCInst to wasm file syntax.

This file contains the declaration of the WebAssemblyMCAsmInfo class.

This file provides WebAssembly-specific target descriptions.

This file contains the declaration of the WebAssembly-specific type parsing utility functions.

static const fltSemantics & IEEEsingle()

static const fltSemantics & IEEEdouble()

static constexpr roundingMode rmNearestTiesToEven

static APFloat getQNaN(const fltSemantics &Sem, bool Negative=false, const APInt *payload=nullptr)

Factory for QNaN values.

Class for arbitrary precision integers.

uint64_t getZExtValue() const

Get zero extended value.

unsigned getBitWidth() const

Return the number of bits in the APInt.

bool isNegative() const

Determine sign of this APInt.

This class is intended to be used as a base class for asm properties and features specific to the tar...

raw_ostream * CommentStream

A stream that comments can be emitted to if desired.

const MCRegisterInfo & MRI

void printAnnotation(raw_ostream &OS, StringRef Annot)

Utility function for printing annotations.

MCInstPrinter(const MCAsmInfo &mai, const MCInstrInfo &mii, const MCRegisterInfo &mri)

Instances of this class represent a single low-level machine instruction.

Describe properties that are true of each instruction in the target description file.

Interface to description of machine instruction set.

Instances of this class represent operands of the MCInst class.

MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...

Wrapper class representing physical registers. Should be passed by value.

constexpr unsigned id() const

Generic base class for all target subtargets.

Represent a reference to a symbol from inside an expression.

const MCSymbol & getSymbol() const

MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...

StringRef getName() const

getName - Get the symbol name.

SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...

StringRef - Represent a constant reference to a string, i.e.

void printWebAssemblySignatureOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O)

Definition WebAssemblyInstPrinter.cpp:373

void printRegName(raw_ostream &OS, MCRegister Reg) override

Print the assembler register name.

Definition WebAssemblyInstPrinter.cpp:41

void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O)

std::pair< const char *, uint64_t > getMnemonic(const MCInst &MI) const override

Returns a pair containing the mnemonic for MI and the number of bits left for further processing by p...

void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, const MCSubtargetInfo &STI, raw_ostream &OS) override

Print the specified MCInst to the specified raw_ostream.

Definition WebAssemblyInstPrinter.cpp:47

void printOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O, bool IsVariadicDef=false)

Definition WebAssemblyInstPrinter.cpp:315

void printBrList(const MCInst *MI, unsigned OpNo, raw_ostream &O)

Definition WebAssemblyInstPrinter.cpp:353

void printCatchList(const MCInst *MI, unsigned OpNo, raw_ostream &O)

Definition WebAssemblyInstPrinter.cpp:393

void printWebAssemblyP2AlignOperand(const MCInst *MI, unsigned OpNo, raw_ostream &O)

Definition WebAssemblyInstPrinter.cpp:364

WebAssemblyInstPrinter(const MCAsmInfo &MAI, const MCInstrInfo &MII, const MCRegisterInfo &MRI)

Definition WebAssemblyInstPrinter.cpp:36

This class implements an extremely fast bulk output stream that can only output to a stream.

unsigned GetDefaultP2Align(unsigned Opc)

static const unsigned UnusedReg

@ OPERAND_BASIC_BLOCK

Basic block label in a branch construct.

std::string signatureToString(const wasm::WasmSignature *Sig)

unsigned getWARegStackId(MCRegister Reg)

const char * anyTypeToString(unsigned Type)

@ WASM_OPCODE_CATCH_ALL_REF

This is an optimization pass for GlobalISel generic memory operations.

std::string utohexstr(uint64_t X, bool LowerCase=false, unsigned Width=0)

std::string utostr(uint64_t X, bool isNeg=false)

DWARFExpression::Operation Op

std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)

decltype(auto) cast(const From &Val)

cast - Return the argument parameter cast to the specified type.