Skip to content

Commit fabcadf

Browse files
authored
Let M68kMCCodeEmitter set Scratch size. (llvm#69898)
The Scratch buffer passed to getBinaryCodeForInst needs to be able to hold any value returned by getMachineOpValue or other custom encoders. It's better to let the caller of getBinaryCodeForInst set the size of Scratch as it's impossible for VarLenCodeEmitterGen to know what the smallest needed size is. VarLenCodeEmitterGen now calculates its smallest needed Scratch bit width based on the slice operations and zero extends Scratch if it's too small. This only guarantees that Scratch has enough bits for the generated code not for getMachineOpValue or custom encoders. The smallest internal APInt representation uses one uint64_t word so there is no point in using a smaller size.
1 parent 851338b commit fabcadf

File tree

3 files changed

+18
-8
lines changed

3 files changed

+18
-8
lines changed

llvm/lib/Target/M68k/MCTargetDesc/M68kMCCodeEmitter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ void M68kMCCodeEmitter::encodeInstruction(const MCInst &MI,
209209

210210
// Try using the new method first.
211211
APInt EncodedInst(16, 0U);
212-
APInt Scratch(16, 0U);
212+
APInt Scratch(64, 0U); // One APInt word is enough.
213213
getBinaryCodeForInstr(MI, Fixups, EncodedInst, Scratch, STI);
214214

215215
ArrayRef<uint64_t> Data(EncodedInst.getRawData(), EncodedInst.getNumWords());

llvm/test/TableGen/VarLenEncoder.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ def FOO32 : MyVarInst<MemOp32<"src">>;
6565
// CHECK: UINT64_C(46848), // FOO32
6666

6767
// CHECK-LABEL: case ::FOO16: {
68-
// CHECK: Scratch = Scratch.zext(41);
68+
// CHECK: Scratch.getBitWidth() < 16
6969
// src.reg
7070
// CHECK: getMachineOpValue(MI, MI.getOperand(1), /*Pos=*/0, Scratch, Fixups, STI);
7171
// CHECK: Inst.insertBits(Scratch.extractBits(8, 0), 0);
@@ -83,7 +83,7 @@ def FOO32 : MyVarInst<MemOp32<"src">>;
8383
// CHECK: Inst.insertBits(Scratch.extractBits(2, 0), 39);
8484

8585
// CHECK-LABEL: case ::FOO32: {
86-
// CHECK: Scratch = Scratch.zext(57);
86+
// CHECK: Scratch.getBitWidth() < 32
8787
// src.reg
8888
// CHECK: getMachineOpValue(MI, MI.getOperand(1), /*Pos=*/0, Scratch, Fixups, STI);
8989
// CHECK: Inst.insertBits(Scratch.extractBits(8, 0), 0);

llvm/utils/TableGen/VarLenCodeEmitterGen.cpp

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@
6060
#include "llvm/TableGen/Error.h"
6161
#include "llvm/TableGen/Record.h"
6262

63+
#include <algorithm>
64+
6365
using namespace llvm;
6466

6567
namespace {
@@ -445,20 +447,17 @@ std::string VarLenCodeEmitterGen::getInstructionCases(Record *R,
445447
std::string VarLenCodeEmitterGen::getInstructionCaseForEncoding(
446448
Record *R, AltEncodingTy Mode, const VarLenInst &VLI, CodeGenTarget &Target,
447449
int I) {
448-
size_t BitWidth = VLI.size();
449450

450451
CodeGenInstruction &CGI = Target.getInstruction(R);
451452

452453
std::string Case;
453454
raw_string_ostream SS(Case);
454-
// Resize the scratch buffer.
455-
if (BitWidth && !VLI.isFixedValueOnly())
456-
SS.indent(I) << "Scratch = Scratch.zext(" << BitWidth << ");\n";
457455
// Populate based value.
458456
SS.indent(I) << "Inst = getInstBits" << Modes[Mode] << "(opcode);\n";
459457

460458
// Process each segment in VLI.
461459
size_t Offset = 0U;
460+
unsigned HighScratchAccess = 0U;
462461
for (const auto &ES : VLI) {
463462
unsigned NumBits = ES.BitWidth;
464463
const Init *Val = ES.Value;
@@ -497,6 +496,8 @@ std::string VarLenCodeEmitterGen::getInstructionCaseForEncoding(
497496
<< "Scratch.extractBits(" << utostr(NumBits) << ", "
498497
<< utostr(LoBit) << ")"
499498
<< ", " << Offset << ");\n";
499+
500+
HighScratchAccess = std::max(HighScratchAccess, NumBits + LoBit);
500501
}
501502
Offset += NumBits;
502503
}
@@ -505,7 +506,16 @@ std::string VarLenCodeEmitterGen::getInstructionCaseForEncoding(
505506
if (!PostEmitter.empty())
506507
SS.indent(I) << "Inst = " << PostEmitter << "(MI, Inst, STI);\n";
507508

508-
return Case;
509+
// Resize the scratch buffer if it's to small.
510+
std::string ScratchResizeStr;
511+
if (VLI.size() && !VLI.isFixedValueOnly()) {
512+
raw_string_ostream RS(ScratchResizeStr);
513+
RS.indent(I) << "if (Scratch.getBitWidth() < " << HighScratchAccess
514+
<< ") { Scratch = Scratch.zext(" << HighScratchAccess
515+
<< "); }\n";
516+
}
517+
518+
return ScratchResizeStr + Case;
509519
}
510520

511521
namespace llvm {

0 commit comments

Comments
 (0)