@@ -1,6 +1,16 @@
2011-03-29 H.J. Lu <hongjiu.lu@intel.com>
PR middle-end/47725
+ PR target/48085
+ * calls.c (precompute_register_parameters): Convert pointer to
+ TLS symbol if needed.
+
+ * config/i386/i386.c (ix86_promote_function_mode): New.
+ (TARGET_PROMOTE_FUNCTION_MODE): Likewise.
+
+2011-03-29 H.J. Lu <hongjiu.lu@intel.com>
+
+ PR middle-end/47725
* combine.c (cant_combine_insn_p): Don't check zero/sign extended
hard registers.
@@ -691,7 +691,13 @@ precompute_register_parameters (int num_actuals, struct arg_data *args,
pseudo now. TLS symbols sometimes need a call to resolve. */
if (CONSTANT_P (args[i].value)
&& !LEGITIMATE_CONSTANT_P (args[i].value))
- args[i].value = force_reg (args[i].mode, args[i].value);
+ {
+ if (GET_MODE (args[i].value) != args[i].mode)
+ args[i].value = convert_to_mode (args[i].mode,
+ args[i].value,
+ args[i].unsignedp);
+ args[i].value = force_reg (args[i].mode, args[i].value);
+ }
/* If we are to promote the function arg to a wider mode,
do it now. */
@@ -7636,6 +7636,23 @@ ix86_function_value (const_tree valtype, const_tree fntype_or_decl,
return ix86_function_value_1 (valtype, fntype_or_decl, orig_mode, mode);
}
+/* Pointer function arguments and return values are promoted to
+ Pmode. */
+
+static enum machine_mode
+ix86_promote_function_mode (const_tree type, enum machine_mode mode,
+ int *punsignedp, const_tree fntype,
+ int for_return)
+{
+ if (for_return != 1 && POINTER_TYPE_P (type))
+ {
+ *punsignedp = POINTERS_EXTEND_UNSIGNED;
+ return Pmode;
+ }
+ return default_promote_function_mode (type, mode, punsignedp, fntype,
+ for_return);
+}
+
rtx
ix86_libcall_value (enum machine_mode mode)
{
@@ -35577,6 +35594,9 @@ ix86_autovectorize_vector_sizes (void)
#undef TARGET_FUNCTION_VALUE_REGNO_P
#define TARGET_FUNCTION_VALUE_REGNO_P ix86_function_value_regno_p
+#undef TARGET_PROMOTE_FUNCTION_MODE
+#define TARGET_PROMOTE_FUNCTION_MODE ix86_promote_function_mode
+
#undef TARGET_SECONDARY_RELOAD
#define TARGET_SECONDARY_RELOAD ix86_secondary_reload