
The ParseOperand function makes use of the two
previously defined functions in order to parse an operand of which
type is originally unknown.
![]() | Note |
|---|---|
This section describes how this function is used in the OpenRISC 1000 implementation, specifically for how it handles memory operands. Other architectures will need to modify this function to match the needs and types of operands expected to be found in an assembly output. |
In the OpenRISC 1000 architecture, there are three types of operand which
need parsing by this method, registers, immediates and memory operands
which are of the form imm(reg).
Firstly attempts are made to parse an operand as a register, using the
previously defined ParseRegister function.
If this succeeds then the operand is added to the list of operands
for the instruction and the function returns.
If this does not work (the operand is not a register), an attempt is then made to parse the operand as an immediate. Should the immediate operand successfully be parsed, then it should be considered as a memory operand first, before placing it into the list of operands.
As the form of a memory operand in OpenRISC 1000 is of the form
imm(reg), then the next token is evaluated to
determine if it is a the start of a memory operand. If this type
matches (i.e. it is a left parenthesis, the next token is evaluated as
a register. Finally should the last token be a right parenthesis, then
a memory operand has instead been parsed.
Should parsing as a memory operand succeed, the two components are added to the operand list whereas if the first test failed (the first operand was not an left parenthesis) just the immediate is added.
If however, no valid operand was found (either not a valid type or memory parsing failed after identifying a left parenthesis), then an error is created and returned instead.
bool OR1KAsmParser::
ParseOperand(SmallVectorImpl<MCParsedAsmOperand*> &Operands) {
OR1KOperand *Op, *Op2 = 0;
// Attempt to parse token as register
unsigned RegNo;
Op = ParseRegister(RegNo);
// Attempt to parse token as immediate
if (!Op) {
Op = ParseImmediate();
// If next token is left parenthesis, then attempt to parse as memory
// operand
if (Op)
if (getLexer().is(AsmToken::LParen)) {
getLexer().Lex();
// Swap tokens around so that they can be parsed
Op2 = Op;
Op = ParseRegister(RegNo);
// Invalid memory operand, fail
if (!Op || getLexer().isNot(AsmToken::RParen)) {
Error(Parser.getTok().getLoc(), "unknown operand");
return true;
}
getLexer().Lex();
}
}
// If the token could not be parsed then fail
if (!Op) {
Error(Parser.getTok().getLoc(), "unknown operand");
return true;
}
// Push back parsed operand(s) into list of operands
Operands.push_back(Op);
if (Op2)
Operands.push_back(Op2);
return false;
}
