Revision: 126768 Author: clattner Date: 2007-05-01 10:59:57 -0700 (Tue, 01 May 2007)
Log Message: ----------- improve support for __builtin_extract_return_address and __builtin_frob_return_address (?) for most targets. This is one step towards solving PR1375, though it is not correct for ARM, SPARC, MIPS etc. Patch by Anton K! Modified Paths: -------------- apple-local/branches/llvm/gcc/llvm-convert.cpp apple-local/branches/llvm/gcc/llvm-internal.h Modified: apple-local/branches/llvm/gcc/llvm-convert.cpp =================================================================== --- apple-local/branches/llvm/gcc/llvm-convert.cpp 2007-05-01 17:49:23 UTC (rev 126767) +++ apple-local/branches/llvm/gcc/llvm-convert.cpp 2007-05-01 17:59:57 UTC (rev 126768) @@ -4071,6 +4071,10 @@ case BUILT_IN_RETURN_ADDRESS: return EmitBuiltinReturnAddr(exp, Result,false); case BUILT_IN_STACK_SAVE: return EmitBuiltinStackSave(exp, Result); case BUILT_IN_STACK_RESTORE: return EmitBuiltinStackRestore(exp); + case BUILT_IN_EXTRACT_RETURN_ADDR: + return EmitBuiltinExtractReturnAddr(exp, Result); + case BUILT_IN_FROB_RETURN_ADDR: + return EmitBuiltinFrobReturnAddr(exp, Result); #define HANDLE_UNARY_FP(F32, F64, V) \ Result = EmitBuiltinUnaryFPOp(V, Intrinsic::F32, Intrinsic::F64) @@ -4162,8 +4166,6 @@ case BUILT_IN_DWARF_SP_COLUMN: case BUILT_IN_INIT_DWARF_REG_SIZES: #endif - case BUILT_IN_FROB_RETURN_ADDR: - case BUILT_IN_EXTRACT_RETURN_ADDR: case BUILT_IN_EH_RETURN: #ifdef EH_RETURN_DATA_REGNO case BUILT_IN_EH_RETURN_DATA_REGNO: @@ -4404,6 +4406,39 @@ return true; } +bool TreeToLLVM::EmitBuiltinExtractReturnAddr(tree exp, Value *&Result) { + tree arglist = TREE_OPERAND(exp, 1); + + Value *Ptr = Emit(TREE_VALUE(arglist), 0); + + // FIXME: Actually we should do something like this: + // + // Result = (Ptr & MASK_RETURN_ADDR) + RETURN_ADDR_OFFSET, if mask and + // offset are defined. This seems to be needed for: ARM, MIPS, Sparc. + // Unfortunately, these constants are defined as RTL expressions and + // should be handled separately. + + Result = CastToType(Instruction::BitCast, Ptr, PointerType::get(Type::Int8Ty)); + + return true; +} + +bool TreeToLLVM::EmitBuiltinFrobReturnAddr(tree exp, Value *&Result) { + tree arglist = TREE_OPERAND(exp, 1); + + Value *Ptr = Emit(TREE_VALUE(arglist), 0); + + // FIXME: Actually we should do something like this: + // + // Result = Ptr - RETURN_ADDR_OFFSET, if offset is defined. This seems to be + // needed for: MIPS, Sparc. Unfortunately, these constants are defined + // as RTL expressions and should be handled separately. + + Result = CastToType(Instruction::BitCast, Ptr, PointerType::get(Type::Int8Ty)); + + return true; +} + bool TreeToLLVM::EmitBuiltinStackSave(tree exp, Value *&Result) { tree arglist = TREE_OPERAND(exp, 1); if (!validate_arglist(arglist, VOID_TYPE)) Modified: apple-local/branches/llvm/gcc/llvm-internal.h =================================================================== --- apple-local/branches/llvm/gcc/llvm-internal.h 2007-05-01 17:49:23 UTC (rev 126767) +++ apple-local/branches/llvm/gcc/llvm-internal.h 2007-05-01 17:59:57 UTC (rev 126768) @@ -524,6 +524,8 @@ bool EmitBuiltinBZero(tree_node *exp, Value *&Result); bool EmitBuiltinPrefetch(tree_node *exp); bool EmitBuiltinReturnAddr(tree_node *exp, Value *&Result, bool isFrame); + bool EmitBuiltinExtractReturnAddr(tree_node *exp, Value *&Result); + bool EmitBuiltinFrobReturnAddr(tree_node *exp, Value *&Result); bool EmitBuiltinStackSave(tree_node *exp, Value *&Result); bool EmitBuiltinStackRestore(tree_node *exp); _______________________________________________ llvm-commits mailing list llvm-commits@cs.uiuc.edu http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits