Skip to content

Commit 3140490

Browse files
committed
ASM blocks
1 parent 0cd20d6 commit 3140490

File tree

8 files changed

+343
-30
lines changed

8 files changed

+343
-30
lines changed

clang/lib/Basic/Targets/Parasol.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,9 @@ void ParasolTargetInfo::getTargetDefines(const LangOptions &Opts,
4747
// Define the __Parasol__ macro when building for this target
4848
Builder.defineMacro("__Parasol__");
4949
}
50+
51+
bool ParasolTargetInfo::validateAsmConstraint(
52+
const char *&Name, TargetInfo::ConstraintInfo &info
53+
) const {
54+
return false;
55+
}

clang/lib/Basic/Targets/Parasol.h

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -63,14 +63,12 @@ class LLVM_LIBRARY_VISIBILITY ParasolTargetInfo : public TargetInfo {
6363
return std::nullopt;
6464
}
6565

66-
bool validateAsmConstraint(const char *&Name,
67-
TargetInfo::ConstraintInfo &info) const override {
68-
return false;
69-
}
70-
7166
std::string_view getClobbers() const override {
7267
return "";
7368
}
69+
70+
bool validateAsmConstraint(const char *&Name,
71+
TargetInfo::ConstraintInfo &info) const override;
7472
};
7573

7674
} // namespace targets

llvm/include/llvm/CodeGen/TargetLowering.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4895,6 +4895,15 @@ class TargetLowering : public TargetLoweringBase {
48954895
return InlineAsm::ConstraintCode::Unknown;
48964896
}
48974897

4898+
/// For the given register class and constraint type, determine the
4899+
/// register MVT.
4900+
virtual MVT getRegVTForConstraintVT(const TargetRegisterInfo *TRI, const TargetRegisterClass *RC, MVT ConstraintVT) const {
4901+
// Get the actual register value type. This is important, because the user
4902+
// may have asked for (e.g.) the AX register in i32 type. We need to
4903+
// remember that AX is actually i16 to get the right extension.
4904+
return *TRI->legalclasstypes_begin(*RC);
4905+
}
4906+
48984907
/// Try to replace an X constraint, which matches anything, with another that
48994908
/// has more specific requirements based on the type of the corresponding
49004909
/// operand. This returns null if there is no replacement to make.

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9118,10 +9118,7 @@ getRegistersForValue(SelectionDAG &DAG, const SDLoc &DL,
91189118
if (!RC)
91199119
return std::nullopt;
91209120

9121-
// Get the actual register value type. This is important, because the user
9122-
// may have asked for (e.g.) the AX register in i32 type. We need to
9123-
// remember that AX is actually i16 to get the right extension.
9124-
const MVT RegVT = *TRI.legalclasstypes_begin(*RC);
9121+
const MVT RegVT = TLI.getRegVTForConstraintVT(&TRI, RC, OpInfo.ConstraintVT);
91259122

91269123
if (OpInfo.ConstraintVT != MVT::Other && RegVT != MVT::Untyped) {
91279124
// If this is an FP operand in an integer register (or visa versa), or more

llvm/lib/Target/Parasol/AsmParser/ParasolAsmParser.cpp

Lines changed: 252 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
//
66
//===----------------------------------------------------------------------===//
77

8+
#include "MCTargetDesc/ParasolInstPrinter.h"
89
#include "ParasolInstrInfo.h"
910
#include "ParasolTargetMachine.h"
1011
#include "TargetInfo/ParasolTargetInfo.h"
@@ -56,6 +57,136 @@ using namespace llvm;
5657

5758
namespace {
5859

60+
/// ARMOperand - Instances of this class represent a parsed ARM machine
61+
/// operand.
62+
class ParasolOperand : public MCParsedAsmOperand {
63+
enum KindTy {
64+
k_Token,
65+
k_Register,
66+
k_Immediate
67+
68+
} Kind;
69+
70+
SMLoc StartLoc, EndLoc, AlignmentLoc;
71+
SmallVector<unsigned, 8> Registers;
72+
73+
struct TokOp {
74+
const char *Data;
75+
unsigned Length;
76+
};
77+
78+
struct RegOp {
79+
unsigned RegNum;
80+
};
81+
82+
struct ImmOp {
83+
const MCExpr *Val;
84+
};
85+
86+
union {
87+
struct TokOp Tok;
88+
struct RegOp Reg;
89+
struct ImmOp Imm;
90+
};
91+
92+
public:
93+
ParasolOperand(KindTy K) : Kind(K) {}
94+
95+
bool isImm() const override { return Kind == k_Immediate; }
96+
97+
bool isToken() const override { return Kind == k_Token; }
98+
99+
bool isMem() const override { return false; }
100+
101+
bool isReg() const override { return Kind == k_Register; }
102+
103+
/// getStartLoc - Get the location of the first token of this operand.
104+
SMLoc getStartLoc() const override { return StartLoc; }
105+
106+
/// getEndLoc - Get the location of the last token of this operand.
107+
SMLoc getEndLoc() const override { return EndLoc; }
108+
109+
/// getLocRange - Get the range between the first and last token of this
110+
/// operand.
111+
SMRange getLocRange() const { return SMRange(StartLoc, EndLoc); }
112+
113+
StringRef getToken() const {
114+
assert(Kind == k_Token && "Invalid access!");
115+
return StringRef(Tok.Data, Tok.Length);
116+
}
117+
118+
unsigned getReg() const override {
119+
assert(Kind == k_Register && "Invalid access!");
120+
return Reg.RegNum;
121+
}
122+
123+
const MCExpr *getImm() const {
124+
assert(isImm() && "Invalid access!");
125+
return Imm.Val;
126+
}
127+
128+
void addRegOperands(MCInst &Inst, unsigned N) const {
129+
assert(N == 1 && "Invalid number of operands!");
130+
Inst.addOperand(MCOperand::createReg(getReg()));
131+
}
132+
133+
void addExpr(MCInst &Inst, const MCExpr *Expr) const {
134+
// Add as immediates when possible. Null MCExpr = 0.
135+
if (!Expr)
136+
Inst.addOperand(MCOperand::createImm(0));
137+
else if (const MCConstantExpr *CE = dyn_cast<MCConstantExpr>(Expr))
138+
Inst.addOperand(MCOperand::createImm(CE->getValue()));
139+
else
140+
Inst.addOperand(MCOperand::createExpr(Expr));
141+
}
142+
143+
void addImmOperands(MCInst &Inst, unsigned N) const {
144+
assert(N == 1 && "Invalid number of operands!");
145+
addExpr(Inst, getImm());
146+
}
147+
148+
void print(raw_ostream &OS) const override;
149+
150+
static std::unique_ptr<ParasolOperand> CreateToken(StringRef Str, SMLoc S) {
151+
auto Op = std::make_unique<ParasolOperand>(k_Token);
152+
Op->Tok.Data = Str.data();
153+
Op->Tok.Length = Str.size();
154+
Op->StartLoc = S;
155+
Op->EndLoc = S;
156+
return Op;
157+
}
158+
159+
static std::unique_ptr<ParasolOperand>
160+
createReg(unsigned RegNo, SMLoc S, SMLoc E, bool IsGPRAsFPR = false) {
161+
auto Op = std::make_unique<ParasolOperand>(k_Register);
162+
Op->Reg.RegNum = RegNo;
163+
Op->StartLoc = S;
164+
Op->EndLoc = E;
165+
return Op;
166+
}
167+
};
168+
169+
void ParasolOperand::print(raw_ostream &OS) const {
170+
auto RegName = [](MCRegister Reg) {
171+
if (Reg)
172+
return ParasolInstPrinter::getRegisterName(Reg);
173+
else
174+
return "noreg";
175+
};
176+
177+
switch (Kind) {
178+
case k_Token:
179+
OS << "'" << getToken() << "'";
180+
break;
181+
case k_Register:
182+
OS << "<register " << RegName(getReg()) << ">";
183+
break;
184+
case k_Immediate:
185+
OS << *getImm();
186+
break;
187+
}
188+
}
189+
59190
class ParasolAsmParser : public MCTargetAsmParser {
60191
MCAsmParser &Parser;
61192
MCInst MCB;
@@ -73,19 +204,18 @@ class ParasolAsmParser : public MCTargetAsmParser {
73204
}
74205

75206
MCAsmLexer &getLexer() const { return Parser.getLexer(); }
76-
207+
SMLoc getLoc() const { return getParser().getTok().getLoc(); }
77208
bool equalIsAsmAssignment() override { return false; }
78209
bool isLabel(AsmToken &Token) override { llvm_unreachable("Unimplemented"); };
79210

80211
void Warning(SMLoc L, const Twine &Msg) { Parser.Warning(L, Msg); }
81212
bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
82213
bool ParseDirectiveFalign(unsigned Size, SMLoc L);
83214

215+
bool parseOperand(OperandVector &, StringRef Mnemonic);
84216
bool parseRegister(MCRegister &Reg, SMLoc &StartLoc, SMLoc &EndLoc) override;
85217
ParseStatus tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
86-
SMLoc &EndLoc) override {
87-
llvm_unreachable("Unimplemented");
88-
}
218+
SMLoc &EndLoc) override;
89219
bool ParseDirectiveSubsection(SMLoc L);
90220
bool ParseDirectiveComm(bool IsLocal, SMLoc L);
91221
bool RegisterMatchesArch(unsigned MatchNum) const;
@@ -101,9 +231,7 @@ class ParasolAsmParser : public MCTargetAsmParser {
101231
bool MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
102232
OperandVector &Operands, MCStreamer &Out,
103233
uint64_t &ErrorInfo,
104-
bool MatchingInlineAsm) override {
105-
llvm_unreachable("Unimplemented");
106-
}
234+
bool MatchingInlineAsm) override;
107235

108236
unsigned validateTargetOperandClass(MCParsedAsmOperand &Op,
109237
unsigned Kind) override {
@@ -132,38 +260,141 @@ class ParasolAsmParser : public MCTargetAsmParser {
132260
}
133261

134262
bool splitIdentifier(OperandVector &Operands);
135-
bool parseOperand(OperandVector &Operands);
136-
bool parseInstruction(OperandVector &Operands);
137263
bool implicitExpressionLocation(OperandVector &Operands);
138264
bool parseExpressionOrOperand(OperandVector &Operands);
139265
bool parseExpression(MCExpr const *&Expr);
140266

141-
bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
142-
SMLoc NameLoc, OperandVector &Operands) override {
143-
llvm_unreachable("Unimplemented");
144-
}
267+
ParseStatus parseRegister(OperandVector &Operands);
145268

146-
bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, AsmToken ID,
147-
OperandVector &Operands) override {
148-
llvm_unreachable("Unimplemented");
149-
}
269+
bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
270+
SMLoc NameLoc, OperandVector &Operands) override;
150271

151272
bool ParseDirective(AsmToken DirectiveID) override {
152273
llvm_unreachable("Unimplemented");
153274
}
154275
};
155276
} // namespace
156277

278+
#define GET_REGISTER_MATCHER
279+
#define GET_SUBTARGET_FEATURE_NAME
280+
#define GET_MATCHER_IMPLEMENTATION
281+
#define GET_MNEMONIC_SPELL_CHECKER
282+
#include "ParasolGenAsmMatcher.inc"
283+
284+
bool ParasolAsmParser::MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
285+
OperandVector &Operands,
286+
MCStreamer &Out,
287+
uint64_t &ErrorInfo,
288+
bool MatchingInlineAsm) {
289+
FeatureBitset MissingFeatures;
290+
MCInst Inst;
291+
292+
auto Result = MatchInstructionImpl(Operands, Inst, ErrorInfo, MissingFeatures,
293+
MatchingInlineAsm);
294+
295+
switch (Result) {
296+
default:
297+
break;
298+
case Match_Success:
299+
Inst.setLoc(IDLoc);
300+
Out.emitInstruction(Inst, getSTI());
301+
return false;
302+
}
303+
304+
llvm_unreachable("Unknown match type detected!");
305+
}
306+
307+
bool ParasolAsmParser::parseOperand(OperandVector &Operands,
308+
StringRef Mnemonic) {
309+
MCAsmParser &Parser = getParser();
310+
SMLoc S, E;
311+
312+
if (parseRegister(Operands).isSuccess()) {
313+
return false;
314+
}
315+
316+
return false;
317+
}
318+
319+
bool ParasolAsmParser::ParseInstruction(ParseInstructionInfo &Info,
320+
StringRef Name, SMLoc NameLoc,
321+
OperandVector &Operands) {
322+
MCAsmParser &Parser = getParser();
323+
324+
Operands.push_back(ParasolOperand::CreateToken(Name, NameLoc));
325+
326+
// Read the remaining operands.
327+
if (getLexer().isNot(AsmToken::EndOfStatement)) {
328+
// Read the first operand.
329+
if (parseOperand(Operands, Name)) {
330+
return true;
331+
}
332+
333+
while (parseOptionalToken(AsmToken::Comma)) {
334+
// Parse and remember the operand.
335+
if (parseOperand(Operands, Name)) {
336+
return true;
337+
}
338+
}
339+
}
340+
341+
return false;
342+
}
343+
344+
static MCRegister matchRegisterNameHelper(StringRef Name) {
345+
MCRegister Reg = MatchRegisterName(Name);
346+
assert(Reg >= Parasol::X0 && Reg <= Parasol::X63);
347+
348+
if (!Reg)
349+
return Parasol::NoRegister;
350+
351+
return Reg;
352+
}
353+
157354
bool ParasolAsmParser::parseRegister(MCRegister &Reg, SMLoc &StartLoc,
158355
SMLoc &EndLoc) {
159-
llvm_unreachable("unimplemented");
356+
if (!tryParseRegister(Reg, StartLoc, EndLoc).isSuccess())
357+
return Error(StartLoc, "invalid register name");
358+
return false;
160359
}
161360

162-
void ParasolAsmParser::convertToMapAndConstraints(
163-
unsigned Kind, const OperandVector &Operands) {
164-
llvm_unreachable("unimplemented");
361+
ParseStatus ParasolAsmParser::tryParseRegister(MCRegister &Reg, SMLoc &StartLoc,
362+
SMLoc &EndLoc) {
363+
const AsmToken &Tok = getParser().getTok();
364+
StartLoc = Tok.getLoc();
365+
EndLoc = Tok.getEndLoc();
366+
StringRef Name = getLexer().getTok().getIdentifier();
367+
368+
Reg = matchRegisterNameHelper(Name);
369+
if (!Reg)
370+
return ParseStatus::NoMatch;
371+
372+
getParser().Lex(); // Eat identifier token.
373+
return ParseStatus::Success;
165374
}
375+
166376
/// Force static initialization.
167377
extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeParasolAsmParser() {
168378
RegisterMCAsmParser<ParasolAsmParser> X(getTheParasolTarget());
169379
}
380+
381+
ParseStatus ParasolAsmParser::parseRegister(OperandVector &Operands) {
382+
SMLoc FirstS = getLoc();
383+
bool HadParens = false;
384+
AsmToken LParen;
385+
386+
switch (getLexer().getKind()) {
387+
default:
388+
return ParseStatus::NoMatch;
389+
case AsmToken::Identifier:
390+
StringRef Name = getLexer().getTok().getIdentifier();
391+
MCRegister RegNo = matchRegisterNameHelper(Name);
392+
393+
SMLoc S = getLoc();
394+
SMLoc E = SMLoc::getFromPointer(S.getPointer() + Name.size());
395+
getLexer().Lex();
396+
Operands.push_back(ParasolOperand::createReg(RegNo, S, E));
397+
}
398+
399+
return ParseStatus::Success;
400+
}

0 commit comments

Comments
 (0)