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; }