Skip to content
This repository was archived by the owner on Sep 2, 2018. It is now read-only.

Commit 61bb96b

Browse files
author
Dylan McKay
committed
Merge pull request #103 from agnat/feature/assembler_operators
[AVR] Implement assembler modifiers
2 parents 26896ec + 375f758 commit 61bb96b

File tree

7 files changed

+244
-216
lines changed

7 files changed

+244
-216
lines changed

lib/Target/AVR/AVRMCInstLower.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,11 @@ LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const
4343

4444
if (TF & AVRII::MO_LO)
4545
{
46-
Expr = AVRMCExpr::createLower8(Expr, Ctx);
46+
Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_LO8, Expr, Ctx);
4747
}
4848
else if (TF & AVRII::MO_HI)
4949
{
50-
Expr = AVRMCExpr::createUpper8(Expr, Ctx);
50+
Expr = AVRMCExpr::create(AVRMCExpr::VK_AVR_HI8,Expr, Ctx);
5151
}
5252
else if (TF != 0)
5353
{

lib/Target/AVR/AsmParser/AVRAsmParser.cpp

+59-85
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include "AVR.h"
1111
#include "MCTargetDesc/AVRMCTargetDesc.h"
1212
#include "AVRRegisterInfo.h"
13+
#include "MCTargetDesc/AVRMCExpr.h"
1314
#include "llvm/ADT/APInt.h"
1415
#include "llvm/ADT/StringSwitch.h"
1516
#include "llvm/MC/MCContext.h"
@@ -56,23 +57,16 @@ class AVRAsmParser : public MCTargetAsmParser {
5657
bool ParseDirective(AsmToken directiveID) override { return true; }
5758

5859

59-
//! Parses an assembly operand.
60-
//! \param Operands A list to add the successfully parsed operand to.
61-
//! \param Mnemonic The mnemonic of the instruction.
62-
//! \return `false` if parsing succeeds, `true` otherwise.
6360
bool parseOperand(OperandVector &Operands, StringRef Mnemonic);
64-
65-
//! Attempts to parse a register.
66-
//! \return The register number, or `-1` if the token is not a register.
67-
int parseRegister();
61+
int parseRegister();
6862
bool tryParseRegisterOperand(OperandVector &Operands);
6963
bool tryParseExpression(OperandVector & Operands);
7064
void appendToken(OperandVector & Operands);
7165

72-
//! Handles target specific special cases. See definition for notes.
66+
// Handles target specific special cases. See definition for notes.
7367
unsigned validateTargetOperandClass(MCParsedAsmOperand &Op, unsigned Kind);
7468

75-
//! Given a register returns the corresponding DREG
69+
// Given a register returns the corresponding DREG
7670
unsigned toDREG(unsigned Reg, unsigned From = AVR::sub_lo) {
7771
return MRI->getMatchingSuperReg(Reg, From, &AVRMCRegisterClasses[AVR::DREGSRegClassID]);
7872
}
@@ -91,18 +85,6 @@ class AVRAsmParser : public MCTargetAsmParser {
9185
MCAsmLexer &getLexer() const { return Parser.getLexer(); }
9286

9387
};
94-
} // end of anonymous namespace
95-
96-
/// @name Auto-generated Match Functions
97-
/// {
98-
99-
//! Matches a register name to a register number.
100-
//! \return The register number, or -1 if the register is invalid.
101-
static unsigned MatchRegisterName(StringRef Name);
102-
103-
/// }
104-
105-
namespace {
10688

10789
/*!
10890
* Represents a parsed AVR machine instruction.
@@ -116,25 +98,15 @@ class AVROperand : public MCParsedAsmOperand {
11698
} Kind;
11799

118100
public:
119-
AVROperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
120-
121-
struct Token {
122-
const char *Data;
123-
unsigned Length;
124-
};
125-
126-
struct Register {
127-
unsigned RegNum;
128-
};
129-
130-
struct Immediate {
131-
const MCExpr *Val;
132-
};
101+
explicit AVROperand(KindTy K) : MCParsedAsmOperand(), Kind(K) {}
102+
explicit AVROperand(StringRef Tok) : MCParsedAsmOperand(), Kind(k_Token), Tok(Tok) {}
103+
explicit AVROperand(unsigned Reg) : MCParsedAsmOperand(), Kind(k_Register), Reg(Reg) {}
104+
explicit AVROperand(MCExpr const* Imm) : MCParsedAsmOperand(), Kind(k_Immediate), Imm(Imm) {}
133105

134106
union {
135-
Token Tok;
136-
Register Reg;
137-
Immediate Imm;
107+
StringRef Tok;
108+
unsigned Reg;
109+
MCExpr const* Imm;
138110
};
139111

140112
SMLoc StartLoc, EndLoc;
@@ -161,30 +133,28 @@ class AVROperand : public MCParsedAsmOperand {
161133
addExpr(Inst,Expr);
162134
}
163135

164-
bool isReg() const { return Kind == k_Register; }
165-
bool isImm() const { return Kind == k_Immediate; }
136+
bool isReg() const { return Kind == k_Register; }
137+
bool isImm() const { return Kind == k_Immediate; }
166138
bool isToken() const { return Kind == k_Token; }
167-
bool isMem() const { return false; }
139+
bool isMem() const { return false; }
168140

169141
StringRef getToken() const {
170142
assert(Kind == k_Token && "Invalid access!");
171-
return StringRef(Tok.Data, Tok.Length);
143+
return Tok;
172144
}
173145

174146
unsigned getReg() const {
175147
assert((Kind == k_Register) && "Invalid access!");
176-
return Reg.RegNum;
148+
return Reg;
177149
}
178150

179151
const MCExpr *getImm() const {
180152
assert((Kind == k_Immediate) && "Invalid access!");
181-
return Imm.Val;
153+
return Imm;
182154
}
183155

184156
static std::unique_ptr<AVROperand> CreateToken(StringRef Str, SMLoc S) {
185-
auto Op = make_unique<AVROperand>(k_Token);
186-
Op->Tok.Data = Str.data();
187-
Op->Tok.Length = Str.size();
157+
auto Op = make_unique<AVROperand>(Str);
188158
Op->StartLoc = S;
189159
Op->EndLoc = S;
190160
return Op;
@@ -193,54 +163,38 @@ class AVROperand : public MCParsedAsmOperand {
193163
/// Internal constructor for register kinds
194164
static std::unique_ptr<AVROperand> CreateReg(unsigned RegNum, SMLoc S,
195165
SMLoc E) {
196-
auto Op = make_unique<AVROperand>(k_Register);
197-
Op->Reg.RegNum = RegNum;
166+
auto Op = make_unique<AVROperand>(RegNum);
198167
Op->StartLoc = S;
199168
Op->EndLoc = E;
200169
return Op;
201170
}
202171

203172
static std::unique_ptr<AVROperand> CreateImm(const MCExpr *Val, SMLoc S, SMLoc E) {
204-
auto Op = make_unique<AVROperand>(k_Immediate);
205-
Op->Imm.Val = Val;
173+
auto Op = make_unique<AVROperand>(Val);
206174
Op->StartLoc = S;
207175
Op->EndLoc = E;
208176
return Op;
209177
}
210178

211-
/*!
212-
* Gets the location of the first token of this operand.
213-
*/
214179
SMLoc getStartLoc() const { return StartLoc; }
215-
/*!
216-
* Gets the location of the last token of this operand.
217-
*/
218-
SMLoc getEndLoc() const { return EndLoc; }
180+
SMLoc getEndLoc() const { return EndLoc; }
219181

220182
virtual void print(raw_ostream &OS) const {
221-
OS << "AVROperand = ";
222-
223183
switch(Kind) {
224-
case k_Token:
225-
OS << "Token(\"" << std::string(Tok.Data, Tok.Length) << "\")";
226-
break;
227-
case k_Register:
228-
OS << "Register(Num = " << Reg.RegNum << ")";
229-
break;
230-
case k_Immediate:
231-
OS << "Immediate(Expr = ";
232-
233-
Imm.Val->print(OS);
234-
235-
OS << ")";
236-
237-
break;
184+
case k_Token: OS << "Token: \"" << Tok << "\""; break;
185+
case k_Register: OS << "Register: " << Reg; break;
186+
case k_Immediate: OS << "Immediate: \""; Imm->print(OS); OS << "\""; break;
238187
}
239-
240188
OS << "\n";
241189
}
242190
};
243-
}
191+
192+
} // end of anonymous namespace
193+
194+
// Auto-generated Match Functions
195+
196+
// Returns the register number, or 0 if the register is invalid.
197+
static unsigned MatchRegisterName(StringRef Name);
244198

245199
bool AVRAsmParser::
246200
MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
@@ -281,7 +235,7 @@ MatchAndEmitInstruction(SMLoc IDLoc, unsigned &Opcode,
281235

282236
int AVRAsmParser::parseRegister() {
283237
const AsmToken &Tok = Parser.getTok();
284-
int RegNum = -1;
238+
int RegNum = 0;
285239
if (Tok.is(AsmToken::Identifier)) {
286240
// check for register pair syntax
287241
if (Parser.getLexer().peekTok().is(AsmToken::Colon)) {
@@ -301,8 +255,7 @@ bool AVRAsmParser::
301255
tryParseRegisterOperand(OperandVector &Operands){
302256

303257
int RegNo = parseRegister();
304-
if (RegNo == -1)
305-
return true;
258+
if (RegNo == 0) return true;
306259

307260
AsmToken const& T = Parser.getTok();
308261
Operands.push_back(AVROperand::CreateReg(RegNo, T.getLoc(), T.getEndLoc()));
@@ -318,10 +271,31 @@ tryParseRegisterOperand(OperandVector &Operands){
318271

319272
bool
320273
AVRAsmParser::tryParseExpression(OperandVector & Operands) {
274+
AVRMCExpr::VariantKind ModifierKind = AVRMCExpr::VK_AVR_None;
321275
SMLoc S = Parser.getTok().getLoc();
276+
277+
// check if we have a target specific modifier (lo8, hi8, &c)
278+
if (Parser.getTok().getKind() == AsmToken::Identifier &&
279+
Parser.getLexer().peekTok().getKind() == AsmToken::LParen)
280+
{
281+
282+
StringRef ModifierName = Parser.getTok().getString();
283+
ModifierKind = AVRMCExpr::getKindByName(ModifierName.str().c_str());
284+
if (ModifierKind != AVRMCExpr::VK_AVR_None) {
285+
Parser.Lex(); Parser.Lex(); // eat modifier name and parenthesis
286+
}
287+
}
288+
289+
// parse (potentially inner) expression
322290
MCExpr const* Expression;
323-
if (getParser().parseExpression(Expression))
324-
return true;
291+
if (getParser().parseExpression(Expression)) return true;
292+
293+
// if we have a modifier wrap the inner expression
294+
if (ModifierKind != AVRMCExpr::VK_AVR_None) {
295+
assert(Parser.getTok().getKind() == AsmToken::RParen);
296+
Parser.Lex(); // eat closing parenthesis
297+
Expression = AVRMCExpr::create(ModifierKind, Expression, getContext());
298+
}
325299

326300
SMLoc E = SMLoc::getFromPointer(Parser.getTok().getLoc().getPointer() - 1);
327301
Operands.push_back(AVROperand::CreateImm(Expression, S, E));
@@ -367,7 +341,7 @@ bool AVRAsmParser::parseOperand(OperandVector &Operands,
367341
appendToken(Operands);
368342
return false;
369343
}
370-
} // switch(getLexer().getKind())
344+
}
371345

372346
// could not parse operand
373347
return true;
@@ -419,12 +393,12 @@ AVRAsmParser::validateTargetOperandClass(MCParsedAsmOperand &AsmOp, unsigned Exp
419393
if (Op.isReg()) {
420394
MatchClassKind Expected(static_cast<MatchClassKind>(ExpectedKind));
421395

422-
// If the instructions uses a register pair but we got a single, lower
396+
// If the instruction uses a register pair but we got a single, lower
423397
// register we perform a "class cast".
424398
if (isSubclass(Expected, MCK_DREGS)) {
425399
unsigned correspondingDREG = toDREG(Op.getReg());
426400
if (correspondingDREG) {
427-
Op.Reg.RegNum = correspondingDREG;
401+
Op.Reg = correspondingDREG;
428402
return Match_Success;
429403
}
430404
}

lib/Target/AVR/MCTargetDesc/AVRAsmBackend.cpp

+16-23
Original file line numberDiff line numberDiff line change
@@ -70,30 +70,23 @@ inline unsigned adjustFixupValue(const MCFixup &Fixup, uint64_t Value,
7070

7171
// Add/subtract and shift
7272
switch (Kind) {
73-
default:
74-
return 0;
75-
case FK_Data_2:
76-
case FK_GPRel_4:
77-
case FK_Data_4:
78-
case FK_Data_8:
79-
break;
80-
case AVR::fixup_7_pcrel:
81-
{
82-
Value = adjustFixupRelCondbr(7, Fixup, Value, Ctx);
83-
break;
73+
default: llvm_unreachable("unhandled fixup"); break;
74+
case FK_Data_2:
75+
case FK_GPRel_4:
76+
case FK_Data_4:
77+
case FK_Data_8:
78+
break;
79+
case AVR::fixup_7_pcrel:
80+
Value = adjustFixupRelCondbr(7, Fixup, Value, Ctx);
81+
break;
82+
case AVR::fixup_13_pcrel:
83+
Value = adjustFixupRelCondbr(13, Fixup, Value, Ctx);
84+
break;
85+
case AVR::fixup_call:
86+
Value = adjustFixupCall(Fixup, Value, Ctx);
87+
break;
8488
}
85-
case AVR::fixup_13_pcrel:
86-
{
87-
Value = adjustFixupRelCondbr(13, Fixup, Value, Ctx);
88-
break;
89-
}
90-
case AVR::fixup_call:
91-
{
92-
Value = adjustFixupCall(Fixup, Value, Ctx);
93-
break;
94-
}
95-
}
96-
89+
9790
return Value;
9891
}
9992
}

0 commit comments

Comments
 (0)