summaryrefslogtreecommitdiffstats
path: root/clang/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
commitdb6d5cb8924b95871660193a2fbb848ab9bcbc68 (patch)
treed8a116d8d4b946fb4752331f926110194ad04e38 /clang/lib/CodeGen/CGStmt.cpp
parente459686aac87fd16a64d9f13dc6a2a07dc799e41 (diff)
downloadbcm5719-llvm-db6d5cb8924b95871660193a2fbb848ab9bcbc68.tar.gz
bcm5719-llvm-db6d5cb8924b95871660193a2fbb848ab9bcbc68.zip
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). llvm-svn: 102188
Diffstat (limited to 'clang/lib/CodeGen/CGStmt.cpp')
-rw-r--r--clang/lib/CodeGen/CGStmt.cpp41
1 files changed, 23 insertions, 18 deletions
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index 70cb1a2eca0..b90e1c40158 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/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);
}
}
OpenPOWER on IntegriCloud