aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGStmt.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2010-04-23 17:27:29 +0000
committerChris Lattner <sabre@nondot.org>2010-04-23 17:27:29 +0000
commitaab64d0b7f41ed30b15ba9210ed859424cbc7455 (patch)
tree07fe1e39bdb62c245c6bfc265c04711e7816a38c /lib/CodeGen/CGStmt.cpp
parentca5cec3b5da9aa6b41c4aeccd0ee1c177825bca4 (diff)
Implement PR6845. We allow matching constraints to have different
input and output types when the smaller value isn't mentioned in the asm string. Extend this support from integers to also allowing fp values to be mismatched (if not mentioned in the asm string). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@102188 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGStmt.cpp')
-rw-r--r--lib/CodeGen/CGStmt.cpp41
1 files changed, 23 insertions, 18 deletions
diff --git a/lib/CodeGen/CGStmt.cpp b/lib/CodeGen/CGStmt.cpp
index 70cb1a2eca..b90e1c4015 100644
--- a/lib/CodeGen/CGStmt.cpp
+++ b/lib/CodeGen/CGStmt.cpp
@@ -981,19 +981,18 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
unsigned InputNo;
for (InputNo = 0; InputNo != S.getNumInputs(); ++InputNo) {
TargetInfo::ConstraintInfo &Input = InputConstraintInfos[InputNo];
- if (Input.hasTiedOperand() &&
- Input.getTiedOperand() == i)
+ if (Input.hasTiedOperand() && Input.getTiedOperand() == i)
break;
}
assert(InputNo != S.getNumInputs() && "Didn't find matching input!");
QualType InputTy = S.getInputExpr(InputNo)->getType();
- QualType OutputTy = OutExpr->getType();
+ QualType OutputType = OutExpr->getType();
uint64_t InputSize = getContext().getTypeSize(InputTy);
- if (getContext().getTypeSize(OutputTy) < InputSize) {
- // Form the asm to return the value as a larger integer type.
- ResultRegTypes.back() = llvm::IntegerType::get(VMContext, (unsigned)InputSize);
+ if (getContext().getTypeSize(OutputType) < InputSize) {
+ // Form the asm to return the value as a larger integer or fp type.
+ ResultRegTypes.back() = ConvertType(InputTy);
}
}
} else {
@@ -1043,18 +1042,20 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
// that is usually cheaper, but LLVM IR should really get an anyext someday.
if (Info.hasTiedOperand()) {
unsigned Output = Info.getTiedOperand();
- QualType OutputTy = S.getOutputExpr(Output)->getType();
+ QualType OutputType = S.getOutputExpr(Output)->getType();
QualType InputTy = InputExpr->getType();
- if (getContext().getTypeSize(OutputTy) >
+ if (getContext().getTypeSize(OutputType) >
getContext().getTypeSize(InputTy)) {
// Use ptrtoint as appropriate so that we can do our extension.
if (isa<llvm::PointerType>(Arg->getType()))
Arg = Builder.CreatePtrToInt(Arg,
llvm::IntegerType::get(VMContext, LLVMPointerWidth));
- unsigned OutputSize = (unsigned)getContext().getTypeSize(OutputTy);
- Arg = Builder.CreateZExt(Arg,
- llvm::IntegerType::get(VMContext, OutputSize));
+ const llvm::Type *OutputTy = ConvertType(OutputType);
+ if (isa<llvm::IntegerType>(OutputTy))
+ Arg = Builder.CreateZExt(Arg, OutputTy);
+ else
+ Arg = Builder.CreateFPExt(Arg, OutputTy);
}
}
@@ -1135,13 +1136,17 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
// the expression, do the conversion.
if (ResultRegTypes[i] != ResultTruncRegTypes[i]) {
const llvm::Type *TruncTy = ResultTruncRegTypes[i];
- // Truncate the integer result to the right size, note that
- // ResultTruncRegTypes can be a pointer.
- uint64_t ResSize = CGM.getTargetData().getTypeSizeInBits(TruncTy);
- Tmp = Builder.CreateTrunc(Tmp, llvm::IntegerType::get(VMContext, (unsigned)ResSize));
-
- if (Tmp->getType() != TruncTy) {
- assert(isa<llvm::PointerType>(TruncTy));
+
+ // Truncate the integer result to the right size, note that TruncTy can be
+ // a pointer.
+ if (TruncTy->isFloatingPointTy())
+ Tmp = Builder.CreateFPTrunc(Tmp, TruncTy);
+ else if (!isa<llvm::PointerType>(TruncTy))
+ Tmp = Builder.CreateTrunc(Tmp, TruncTy);
+ else {
+ uint64_t ResSize = CGM.getTargetData().getTypeSizeInBits(TruncTy);
+ Tmp = Builder.CreateTrunc(Tmp, llvm::IntegerType::get(VMContext,
+ (unsigned)ResSize));
Tmp = Builder.CreateIntToPtr(Tmp, TruncTy);
}
}