void emitLoadStoreSymbol(MCInst &Inst, unsigned Opcode, SMLoc IDLoc,
MCStreamer &Out, bool HasTmpReg);
+ // Checks that a PseudoAddTPRel is using x4/tp in its second input operand.
+ // Enforcing this using a restricted register class for the second input
+ // operand of PseudoAddTPRel results in a poor diagnostic due to the fact
+ // 'add' is an overloaded mnemonic.
+ bool checkPseudoAddTPRel(MCInst &Inst, OperandVector &Operands);
+
/// Helper for processing MC instructions that have been successfully matched
/// by MatchAndEmitInstruction. Modifications to the emitted instructions,
/// like the expansion of pseudo instructions (e.g., "li"), can be performed
/// in this method.
- bool processInstruction(MCInst &Inst, SMLoc IDLoc, MCStreamer &Out);
+ bool processInstruction(MCInst &Inst, SMLoc IDLoc, OperandVector &Operands,
+ MCStreamer &Out);
// Auto-generated instruction matching functions
#define GET_ASSEMBLER_HEADER
default:
break;
case Match_Success:
- return processInstruction(Inst, IDLoc, Out);
+ return processInstruction(Inst, IDLoc, Operands, Out);
case Match_MissingFeature:
return Error(IDLoc, "instruction use requires an option to be enabled");
case Match_MnemonicFail:
Opcode, IDLoc, Out);
}
+bool RISCVAsmParser::checkPseudoAddTPRel(MCInst &Inst,
+ OperandVector &Operands) {
+ assert(Inst.getOpcode() == RISCV::PseudoAddTPRel && "Invalid instruction");
+ assert(Inst.getOperand(2).isReg() && "Unexpected second operand kind");
+ if (Inst.getOperand(2).getReg() != RISCV::X4) {
+ SMLoc ErrorLoc = ((RISCVOperand &)*Operands[3]).getStartLoc();
+ return Error(ErrorLoc, "the second input operand must be tp/x4 when using "
+ "%tprel_add modifier");
+ }
+
+ return false;
+}
+
bool RISCVAsmParser::processInstruction(MCInst &Inst, SMLoc IDLoc,
+ OperandVector &Operands,
MCStreamer &Out) {
Inst.setLoc(IDLoc);
case RISCV::PseudoFSD:
emitLoadStoreSymbol(Inst, RISCV::FSD, IDLoc, Out, /*HasTmpReg=*/true);
return false;
+ case RISCV::PseudoAddTPRel:
+ if (checkPseudoAddTPRel(Inst, Operands))
+ return true;
}
emitToStreamer(Out, Inst);
# TP-relative symbol names require a %tprel_add modifier.
add a0, a0, tp, zero # CHECK: :[[@LINE]]:17: error: expected '%' for operand modifier
add a0, a0, tp, %hi(foo) # CHECK: :[[@LINE]]:17: error: operand must be a symbol with %tprel_add modifier
+add a0, tp, a0, %tprel_add(foo) # CHECK: :[[@LINE]]:13: error: the second input operand must be tp/x4 when using %tprel_add modifier
# Unrecognized operand modifier
addi t0, sp, %modifer(255) # CHECK: :[[@LINE]]:15: error: unrecognized operand modifier