Expr *AsmStmt::getInputExpr(unsigned i) {
return cast<Expr>(Exprs[i + NumOutputs]);
}
+void AsmStmt::setInputExpr(unsigned i, Expr *E) {
+ Exprs[i + NumOutputs] = E;
+}
+
/// getInputConstraint - Return the specified input constraint. Unlike output
/// constraints, these can be empty.
if (!Info.hasTiedOperand()) continue;
unsigned TiedTo = Info.getTiedOperand();
+ unsigned InputOpNo = i+NumOutputs;
Expr *OutputExpr = Exprs[TiedTo];
- Expr *InputExpr = Exprs[i+NumOutputs];
+ Expr *InputExpr = Exprs[InputOpNo];
QualType InTy = InputExpr->getType();
QualType OutTy = OutputExpr->getType();
if (Context.hasSameType(InTy, OutTy))
// If this is a reference to the input and if the input was the smaller
// one, then we have to reject this asm.
- if (isOperandMentioned(i+NumOutputs, Pieces)) {
+ if (isOperandMentioned(InputOpNo, Pieces)) {
// This is a use in the asm string of the smaller operand. Since we
// codegen this by promoting to a wider value, the asm will get printed
// "wrong".
OutputConstraintInfos[TiedTo].allowsRegister())
continue;
+ // Either both of the operands were mentioned or the smaller one was
+ // mentioned. One more special case that we'll allow: if the tied input is
+ // integer, unmentioned, and is a constant, then we'll allow truncating it
+ // down to the size of the destination.
+ if (InputDomain == AD_Int && OutputDomain == AD_Int &&
+ !isOperandMentioned(InputOpNo, Pieces) &&
+ InputExpr->isEvaluatable(Context)) {
+ ImpCastExprToType(InputExpr, OutTy, CK_IntegralCast);
+ Exprs[InputOpNo] = InputExpr;
+ NS->setInputExpr(i, InputExpr);
+ continue;
+ }
+
Diag(InputExpr->getLocStart(),
diag::err_asm_tying_incompatible_types)
<< InTy << OutTy << OutputExpr->getSourceRange()