Re: [llvm-commits] [129555] Implement missing dwarf builtins, used by the libstdc++ unwinder.

2007-07-15 Thread Duncan Sands
Can you please also apply it on the 4.2 branch.  I would do it myself
but it hasn't turned up in the mirror yet (which is strange - maybe
something is wrong with the mirror?), and I think you changed it a bit
compared to the version in bugzilla.

Thanks,

Duncan.
___
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits


[llvm-commits] [129555] Implement missing dwarf builtins, used by the libstdc++ unwinder.

2007-07-14 Thread clattner
Revision: 129555
Author:   clattner
Date: 2007-07-14 11:39:13 -0700 (Sat, 14 Jul 2007)

Log Message:
---
Implement missing dwarf builtins, used by the libstdc++ unwinder.
This is more or less workable on x86-32/linux only

Patch by Anton Korobeynikov

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-07-14 07:20:19 UTC 
(rev 129554)
+++ apple-local/branches/llvm/gcc/llvm-convert.cpp  2007-07-14 18:39:13 UTC 
(rev 129555)
@@ -59,8 +59,10 @@
 #include target.h
 #include hard-reg-set.h
 #include except.h
+#include rtl.h
 extern bool tree_could_throw_p(tree);  // tree-flow.h uses non-C++ C 
constructs.
 extern int get_pointer_alignment (tree exp, unsigned int max_align);
+extern enum machine_mode reg_raw_mode[FIRST_PSEUDO_REGISTER];
 }
 
 #define ITANIUM_STYLE_EXCEPTIONS
@@ -4140,7 +4142,25 @@
return EmitBuiltinExtractReturnAddr(exp, Result);
   case BUILT_IN_FROB_RETURN_ADDR:
return EmitBuiltinFrobReturnAddr(exp, Result);
-
+
+  // Builtins used by the exception handling runtime.
+  case BUILT_IN_DWARF_CFA:
+return EmitBuiltinDwarfCFA(exp, Result);
+#ifdef DWARF2_UNWIND_INFO
+  case BUILT_IN_DWARF_SP_COLUMN:
+return EmitBuiltinDwarfSPColumn(exp, Result);
+  case BUILT_IN_INIT_DWARF_REG_SIZES:
+return EmitBuiltinInitDwarfRegSizes(exp, Result);
+#endif
+  case BUILT_IN_EH_RETURN:
+return EmitBuiltinEHReturn(exp, Result);
+#ifdef EH_RETURN_DATA_REGNO
+  case BUILT_IN_EH_RETURN_DATA_REGNO:
+return EmitBuiltinEHReturnDataRegno(exp, Result);
+#endif
+  case BUILT_IN_UNWIND_INIT:
+return EmitBuiltinUnwindInit(exp, Result);
+
 #define HANDLE_UNARY_FP(F32, F64, V) \
 Result = EmitBuiltinUnaryFPOp(V, Intrinsic::F32, Intrinsic::F64)
 
@@ -4216,19 +4236,8 @@
 case BUILT_IN_LONGJMP:
 case BUILT_IN_UPDATE_SETJMP_BUF:
 case BUILT_IN_TRAP:
-  
-  // Various hooks for the DWARF 2 __throw routine.
-case BUILT_IN_UNWIND_INIT:
-case BUILT_IN_DWARF_CFA:
-#ifdef DWARF2_UNWIND_INFO
-case BUILT_IN_DWARF_SP_COLUMN:
-case BUILT_IN_INIT_DWARF_REG_SIZES:
-#endif
-case BUILT_IN_EH_RETURN:
-#ifdef EH_RETURN_DATA_REGNO
-case BUILT_IN_EH_RETURN_DATA_REGNO:
-#endif
-  // FIXME: HACK: Just ignore these.
+
+// FIXME: HACK: Just ignore these.
 {
   const Type *Ty = ConvertType(TREE_TYPE(exp));
   if (Ty != Type::VoidTy)
@@ -4509,6 +4518,171 @@
   return true;
 }
 
+
+// Builtins used by the exception handling runtime.
+
+// On most machines, the CFA coincides with the first incoming parm.
+#ifndef ARG_POINTER_CFA_OFFSET
+#define ARG_POINTER_CFA_OFFSET(FNDECL) FIRST_PARM_OFFSET (FNDECL)
+#endif
+
+// The mapping from gcc register number to DWARF 2 CFA column number.  By
+// default, we just provide columns for all registers.
+#ifndef DWARF_FRAME_REGNUM
+#define DWARF_FRAME_REGNUM(REG) DBX_REGISTER_NUMBER (REG)
+#endif
+
+// Map register numbers held in the call frame info that gcc has
+// collected using DWARF_FRAME_REGNUM to those that should be output in
+// .debug_frame and .eh_frame.
+#ifndef DWARF2_FRAME_REG_OUT
+#define DWARF2_FRAME_REG_OUT(REGNO, FOR_EH) (REGNO)
+#endif
+
+/* Registers that get partially clobbered by a call in a given mode.
+   These must not be call used registers.  */
+#ifndef HARD_REGNO_CALL_PART_CLOBBERED
+#define HARD_REGNO_CALL_PART_CLOBBERED(REGNO, MODE) 0
+#endif
+
+bool TreeToLLVM::EmitBuiltinDwarfCFA(tree exp, Value *Result) {
+  if (!validate_arglist(TREE_OPERAND(exp, 1), VOID_TYPE))
+return false;
+
+  int cfa_offset = ARG_POINTER_CFA_OFFSET(0);
+
+  Result = Builder.CreateCall(Intrinsic::getDeclaration(TheModule,
+  Intrinsic::eh_dwarf_cfa),
+  ConstantInt::get(Type::Int32Ty, cfa_offset));
+
+  return true;
+}
+
+bool TreeToLLVM::EmitBuiltinDwarfSPColumn(tree exp, Value *Result) {
+  if (!validate_arglist(TREE_OPERAND(exp, 1), VOID_TYPE))
+return false;
+
+  unsigned int dwarf_regnum = DWARF_FRAME_REGNUM(STACK_POINTER_REGNUM);
+  Result = ConstantInt::get(ConvertType(TREE_TYPE(exp)), dwarf_regnum);
+
+  return true;
+}
+
+bool TreeToLLVM::EmitBuiltinEHReturnDataRegno(tree exp, Value *Result) {
+  tree arglist = TREE_OPERAND(exp, 1);
+
+  if (!validate_arglist(arglist, INTEGER_TYPE, VOID_TYPE))
+return false;
+
+  tree which = TREE_VALUE (arglist);
+  unsigned HOST_WIDE_INT iwhich;
+
+  if (TREE_CODE (which) != INTEGER_CST) {
+error (argument of %__builtin_eh_return_regno% must be constant);
+return false;
+  }
+
+  iwhich = tree_low_cst (which, 1);
+  iwhich = EH_RETURN_DATA_REGNO (iwhich);
+  if (iwhich == INVALID_REGNUM)
+return false;
+
+  iwhich = DWARF_FRAME_REGNUM (iwhich);
+
+  Result =