Commit a7df97e6 by Michael Meissner

Fix int<->floating point conversion routines

From-SVN: r12379
parent 60725c78
...@@ -36,6 +36,7 @@ Boston, MA 02111-1307, USA. */ ...@@ -36,6 +36,7 @@ Boston, MA 02111-1307, USA. */
#include "expr.h" #include "expr.h"
#include "obstack.h" #include "obstack.h"
#include "tree.h" #include "tree.h"
#include "function.h"
#ifndef TARGET_NO_PROTOTYPE #ifndef TARGET_NO_PROTOTYPE
#define TARGET_NO_PROTOTYPE 0 #define TARGET_NO_PROTOTYPE 0
...@@ -2084,6 +2085,66 @@ rs6000_finalize_pic () ...@@ -2084,6 +2085,66 @@ rs6000_finalize_pic ()
} }
/* Define the structure for the machine field in struct function. */
struct machine_function
{
int sysv_varargs_p;
int save_toc_p;
int fpmem_size;
int fpmem_offset;
};
/* Functions to save and restore rs6000_fpmem_size.
These will be called, via pointer variables,
from push_function_context and pop_function_context. */
void
rs6000_save_machine_status (p)
struct function *p;
{
struct machine_function *machine =
(struct machine_function *) xmalloc (sizeof (struct machine_function));
p->machine = machine;
machine->sysv_varargs_p = rs6000_sysv_varargs_p;
machine->save_toc_p = rs6000_save_toc_p;
machine->fpmem_size = rs6000_fpmem_size;
machine->fpmem_offset = rs6000_fpmem_offset;
}
void
rs6000_restore_machine_status (p)
struct function *p;
{
struct machine_function *machine = p->machine;
rs6000_sysv_varargs_p = machine->sysv_varargs_p;
rs6000_save_toc_p = machine->save_toc_p;
rs6000_fpmem_size = machine->fpmem_size;
rs6000_fpmem_offset = machine->fpmem_offset;
free (machine);
p->machine = (struct machine_function *)0;
}
/* Do anything needed before RTL is emitted for each function. */
void
rs6000_init_expanders ()
{
/* Reset varargs and save TOC indicator */
rs6000_sysv_varargs_p = 0;
rs6000_save_toc_p = 0;
rs6000_fpmem_size = 0;
rs6000_fpmem_offset = 0;
pic_offset_table_rtx = (rtx)0;
/* Arrange to save and restore machine status around nested functions. */
save_machine_status = rs6000_save_machine_status;
restore_machine_status = rs6000_restore_machine_status;
}
/* Print an operand. Recognize special options, documented below. */ /* Print an operand. Recognize special options, documented below. */
#ifdef TARGET_SDATA #ifdef TARGET_SDATA
...@@ -2720,15 +2781,15 @@ rs6000_makes_calls () ...@@ -2720,15 +2781,15 @@ rs6000_makes_calls ()
+---------------------------------------+ +---------------------------------------+
| Parameter save area (P) | 24 | Parameter save area (P) | 24
+---------------------------------------+ +---------------------------------------+
| Float/int conversion temporary (X) | 24+P | Alloca space (A) | 24+P
+---------------------------------------+ +---------------------------------------+
| Alloca space (A) | 24+P+X | Local variable space (L) | 24+P+A
+---------------------------------------+ +---------------------------------------+
| Local variable space (L) | 24+P+X+A | Float/int conversion temporary (X) | 24+P+A+L
+---------------------------------------+ +---------------------------------------+
| Save area for GP registers (G) | 24+P+X+A+L | Save area for GP registers (G) | 24+P+A+X+L
+---------------------------------------+ +---------------------------------------+
| Save area for FP registers (F) | 24+P+X+A+L+G | Save area for FP registers (F) | 24+P+A+X+L+G
+---------------------------------------+ +---------------------------------------+
old SP->| back chain to caller's caller | old SP->| back chain to caller's caller |
+---------------------------------------+ +---------------------------------------+
...@@ -2742,19 +2803,19 @@ rs6000_makes_calls () ...@@ -2742,19 +2803,19 @@ rs6000_makes_calls ()
+---------------------------------------+ +---------------------------------------+
| Parameter save area (P) | 8 | Parameter save area (P) | 8
+---------------------------------------+ +---------------------------------------+
| Float/int conversion temporary (X) | 8+P | Alloca space (A) | 8+P
+---------------------------------------+ +---------------------------------------+
| Alloca space (A) | 8+P+X | Varargs save area (V) | 8+P+A
+---------------------------------------+ +---------------------------------------+
| Varargs save area (V) | 8+P+X+A | Local variable space (L) | 8+P+A+V
+---------------------------------------+ +---------------------------------------+
| Local variable space (L) | 8+P+X+A+V | Float/int conversion temporary (X) | 8+P+A+V+L
+---------------------------------------+ +---------------------------------------+
| saved CR (C) | 8+P+X+A+V+L | saved CR (C) | 8+P+A+V+L+X
+---------------------------------------+ +---------------------------------------+
| Save area for GP registers (G) | 8+P+X+A+V+L+C | Save area for GP registers (G) | 8+P+A+V+L+X+C
+---------------------------------------+ +---------------------------------------+
| Save area for FP registers (F) | 8+P+X+A+V+L+C+G | Save area for FP registers (F) | 8+P+A+V+L+X+C+G
+---------------------------------------+ +---------------------------------------+
old SP->| back chain to caller's caller | old SP->| back chain to caller's caller |
+---------------------------------------+ +---------------------------------------+
...@@ -2777,23 +2838,23 @@ rs6000_makes_calls () ...@@ -2777,23 +2838,23 @@ rs6000_makes_calls ()
+---------------------------------------+ +---------------------------------------+
| Parameter save area (P) | 24 | Parameter save area (P) | 24
+---------------------------------------+ +---------------------------------------+
| Float/int conversion temporary (X) | 24+P | Alloca space (A) | 24+P
+---------------------------------------+ +---------------------------------------+
| Alloca space (A) | 24+P+X | Local variable space (L) | 24+P+A
+---------------------------------------+ +---------------------------------------+
| Local variable space (L) | 24+P+X+A | Float/int conversion temporary (X) | 24+P+A+L
+---------------------------------------+
| Save area for FP registers (F) | 24+P+X+A+L
+---------------------------------------+
| Possible alignment area (X) | 24+P+X+A+L+F
+---------------------------------------+ +---------------------------------------+
| Save area for GP registers (G) | 24+P+X+A+L+F+X | Save area for FP registers (F) | 24+P+A+L+X
+---------------------------------------+ +---------------------------------------+
| Save area for CR (C) | 24+P+X+A+L+F+X+G | Possible alignment area (Y) | 24+P+A+L+X+F
+---------------------------------------+ +---------------------------------------+
| Save area for TOC (T) | 24+P+X+A+L+F+X+G+C | Save area for GP registers (G) | 24+P+A+L+X+F+Y
+---------------------------------------+ +---------------------------------------+
| Save area for LR (R) | 24+P+X+A+L+F+X+G+C+T | Save area for CR (C) | 24+P+A+L+X+F+Y+G
+---------------------------------------+
| Save area for TOC (T) | 24+P+A+L+X+F+Y+G+C
+---------------------------------------+
| Save area for LR (R) | 24+P+A+L+X+F+Y+G+C+T
+---------------------------------------+ +---------------------------------------+
old SP->| back chain to caller's caller | old SP->| back chain to caller's caller |
+---------------------------------------+ +---------------------------------------+
...@@ -2941,7 +3002,6 @@ rs6000_stack_info () ...@@ -2941,7 +3002,6 @@ rs6000_stack_info ()
|| info_ptr->total_size > 220); || info_ptr->total_size > 220);
/* Calculate the offsets */ /* Calculate the offsets */
info_ptr->fpmem_offset = info_ptr->total_size - info_ptr->parm_size;
switch (abi) switch (abi)
{ {
case ABI_NONE: case ABI_NONE:
...@@ -2961,9 +3021,9 @@ rs6000_stack_info () ...@@ -2961,9 +3021,9 @@ rs6000_stack_info ()
case ABI_SOLARIS: case ABI_SOLARIS:
info_ptr->fp_save_offset = - info_ptr->fp_size; info_ptr->fp_save_offset = - info_ptr->fp_size;
info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size; info_ptr->gp_save_offset = info_ptr->fp_save_offset - info_ptr->gp_size;
info_ptr->cr_save_offset = info_ptr->gp_save_offset - reg_size; info_ptr->cr_save_offset = info_ptr->gp_save_offset - info_ptr->cr_size;
info_ptr->toc_save_offset = info_ptr->cr_save_offset - info_ptr->cr_size; info_ptr->toc_save_offset = info_ptr->cr_save_offset - info_ptr->toc_size;
info_ptr->main_save_offset = info_ptr->toc_save_offset - info_ptr->toc_size; info_ptr->main_save_offset = info_ptr->toc_save_offset - info_ptr->main_size;
info_ptr->lr_save_offset = reg_size; info_ptr->lr_save_offset = reg_size;
break; break;
...@@ -2980,6 +3040,9 @@ rs6000_stack_info () ...@@ -2980,6 +3040,9 @@ rs6000_stack_info ()
break; break;
} }
if (info_ptr->fpmem_p)
info_ptr->fpmem_offset = STARTING_FRAME_OFFSET - info_ptr->total_size + info_ptr->vars_size;
/* Zero offsets if we're not saving those registers */ /* Zero offsets if we're not saving those registers */
if (!info_ptr->fp_size) if (!info_ptr->fp_size)
info_ptr->fp_save_offset = 0; info_ptr->fp_save_offset = 0;
...@@ -3004,9 +3067,7 @@ rs6000_stack_info () ...@@ -3004,9 +3067,7 @@ rs6000_stack_info ()
else else
{ {
rs6000_fpmem_size = info_ptr->fpmem_size; rs6000_fpmem_size = info_ptr->fpmem_size;
rs6000_fpmem_offset = STACK_DYNAMIC_OFFSET (current_function_decl) - info_ptr->fpmem_size; rs6000_fpmem_offset = info_ptr->total_size + info_ptr->fpmem_offset;
if (rs6000_fpmem_offset > 32767)
abort ();
} }
return info_ptr; return info_ptr;
...@@ -3792,13 +3853,6 @@ output_epilog (file, size) ...@@ -3792,13 +3853,6 @@ output_epilog (file, size)
fputs ("\t.byte 31\n", file); fputs ("\t.byte 31\n", file);
} }
/* Reset varargs and save TOC indicator */
rs6000_sysv_varargs_p = 0;
rs6000_save_toc_p = 0;
rs6000_fpmem_size = 0;
rs6000_fpmem_offset = 0;
pic_offset_table_rtx = (rtx)0;
if (DEFAULT_ABI == ABI_NT) if (DEFAULT_ABI == ABI_NT)
{ {
RS6000_OUTPUT_BASENAME (file, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); RS6000_OUTPUT_BASENAME (file, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));
......
...@@ -1190,6 +1190,10 @@ extern int rs6000_sysv_varargs_p; ...@@ -1190,6 +1190,10 @@ extern int rs6000_sysv_varargs_p;
/* Align an address */ /* Align an address */
#define ALIGN(n,a) (((n) + (a) - 1) & ~((a) - 1)) #define ALIGN(n,a) (((n) + (a) - 1) & ~((a) - 1))
/* Initialize data used by insn expanders. This is called from
init_emit, once for each function, before code is generated. */
#define INIT_EXPANDERS rs6000_init_expanders ()
/* Size of V.4 varargs area in bytes */ /* Size of V.4 varargs area in bytes */
#define RS6000_VARARGS_SIZE \ #define RS6000_VARARGS_SIZE \
((GP_ARG_NUM_REG * (TARGET_32BIT ? 4 : 8)) + (FP_ARG_NUM_REG * 8) + 8) ((GP_ARG_NUM_REG * (TARGET_32BIT ? 4 : 8)) + (FP_ARG_NUM_REG * 8) + 8)
...@@ -1197,7 +1201,6 @@ extern int rs6000_sysv_varargs_p; ...@@ -1197,7 +1201,6 @@ extern int rs6000_sysv_varargs_p;
/* Offset of V.4 varargs area */ /* Offset of V.4 varargs area */
#define RS6000_VARARGS_OFFSET \ #define RS6000_VARARGS_OFFSET \
(ALIGN (current_function_outgoing_args_size, 8) \ (ALIGN (current_function_outgoing_args_size, 8) \
+ ALIGN (rs6000_fpmem_size, 8) \
+ RS6000_SAVE_AREA) + RS6000_SAVE_AREA)
/* Offset within stack frame to start allocating local variables at. /* Offset within stack frame to start allocating local variables at.
...@@ -1211,7 +1214,6 @@ extern int rs6000_sysv_varargs_p; ...@@ -1211,7 +1214,6 @@ extern int rs6000_sysv_varargs_p;
#define STARTING_FRAME_OFFSET \ #define STARTING_FRAME_OFFSET \
(ALIGN (current_function_outgoing_args_size, 8) \ (ALIGN (current_function_outgoing_args_size, 8) \
+ ALIGN (rs6000_fpmem_size, 8) \
+ RS6000_VARARGS_AREA \ + RS6000_VARARGS_AREA \
+ RS6000_SAVE_AREA) + RS6000_SAVE_AREA)
...@@ -1223,7 +1225,6 @@ extern int rs6000_sysv_varargs_p; ...@@ -1223,7 +1225,6 @@ extern int rs6000_sysv_varargs_p;
machines. See `function.c' for details. */ machines. See `function.c' for details. */
#define STACK_DYNAMIC_OFFSET(FUNDECL) \ #define STACK_DYNAMIC_OFFSET(FUNDECL) \
(ALIGN (current_function_outgoing_args_size, 8) \ (ALIGN (current_function_outgoing_args_size, 8) \
+ ALIGN (rs6000_fpmem_size, 8) \
+ (STACK_POINTER_OFFSET)) + (STACK_POINTER_OFFSET))
/* If we generate an insn to push BYTES bytes, /* If we generate an insn to push BYTES bytes,
...@@ -3009,6 +3010,7 @@ do { \ ...@@ -3009,6 +3010,7 @@ do { \
extern int flag_pic; extern int flag_pic;
extern int optimize; extern int optimize;
extern int flag_expensive_optimizations; extern int flag_expensive_optimizations;
extern int frame_pointer_needed;
/* Declare functions in rs6000.c */ /* Declare functions in rs6000.c */
extern void output_options (); extern void output_options ();
...@@ -3071,6 +3073,9 @@ extern int addrs_ok_for_quad_peep (); ...@@ -3071,6 +3073,9 @@ extern int addrs_ok_for_quad_peep ();
extern enum reg_class secondary_reload_class (); extern enum reg_class secondary_reload_class ();
extern int ccr_bit (); extern int ccr_bit ();
extern void rs6000_finalize_pic (); extern void rs6000_finalize_pic ();
extern void rs6000_save_machine_status ();
extern void rs6000_restore_machine_status ();
extern void rs6000_init_expanders ();
extern void print_operand (); extern void print_operand ();
extern void print_operand_address (); extern void print_operand_address ();
extern int first_reg_to_save (); extern int first_reg_to_save ();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment