#include "clang/Basic/PrettyStackTrace.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
-#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/InlineAsm.h"
static std::string
AddVariableConstraints(const std::string &Constraint, const Expr &AsmExpr,
const TargetInfo &Target, CodeGenModule &CGM,
- const AsmStmt &Stmt, const bool EarlyClobber,
- std::string *GCCReg = nullptr) {
+ const AsmStmt &Stmt, const bool EarlyClobber) {
const DeclRefExpr *AsmDeclRef = dyn_cast<DeclRefExpr>(&AsmExpr);
if (!AsmDeclRef)
return Constraint;
}
// Canonicalize the register here before returning it.
Register = Target.getNormalizedGCCRegisterName(Register);
- if (GCCReg != nullptr)
- *GCCReg = Register.str();
return (EarlyClobber ? "&{" : "{") + Register.str() + "}";
}
// Keep track of out constraints for tied input operand.
std::vector<std::string> OutputConstraints;
- // Keep track of defined physregs.
- llvm::SmallSet<std::string, 8> PhysRegOutputs;
-
// An inline asm can be marked readonly if it meets the following conditions:
// - it doesn't have any sideeffects
// - it doesn't clobber memory
const Expr *OutExpr = S.getOutputExpr(i);
OutExpr = OutExpr->IgnoreParenNoopCasts(getContext());
- std::string GCCReg;
OutputConstraint = AddVariableConstraints(OutputConstraint, *OutExpr,
getTarget(), CGM, S,
- Info.earlyClobber(),
- &GCCReg);
- // Give an error on multiple outputs to same physreg.
- if (!GCCReg.empty() && !PhysRegOutputs.insert(GCCReg).second)
- CGM.Error(S.getAsmLoc(), "multiple outputs to hard register: " + GCCReg);
-
+ Info.earlyClobber());
OutputConstraints.push_back(OutputConstraint);
LValue Dest = EmitLValue(OutExpr);
if (!Constraints.empty())
LargestVectorWidth =
std::max((uint64_t)LargestVectorWidth,
VT->getPrimitiveSizeInBits().getKnownMinSize());
- // Don't tie physregs.
- if (Info.allowsRegister() && GCCReg.empty())
+ if (Info.allowsRegister())
InOutConstraints += llvm::utostr(i);
else
InOutConstraints += OutputConstraint;
// CHECK: [[RESULT:%.*]] = tail call fp128 asm "axbr $0, $2", "=f,0,f"(fp128 %f, fp128 %g)
// CHECK: store fp128 [[RESULT]], fp128* [[DEST]]
}
-
-// Test that there are no tied physreg uses. TwoAddress pass cannot deal with them.
-int test_physregs(void) {
- // CHECK-LABEL: define signext i32 @test_physregs()
- register int l __asm__("r7") = 0;
-
- // CHECK: call i32 asm "lr $0, $1", "={r7},{r7}"
- __asm__("lr %0, %1" : "+r"(l));
-
- // CHECK: call i32 asm "$0 $1 $2", "={r7},{r7},{r7}"
- __asm__("%0 %1 %2" : "+r"(l) : "r"(l));
-
- return l;
-}