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 | Save area for FP registers (F) | 24+P+A+L+X
+---------------------------------------+ +---------------------------------------+
| Possible alignment area (X) | 24+P+X+A+L+F | Possible alignment area (Y) | 24+P+A+L+X+F
+---------------------------------------+ +---------------------------------------+
| Save area for GP registers (G) | 24+P+X+A+L+F+X | Save area for GP registers (G) | 24+P+A+L+X+F+Y
+---------------------------------------+ +---------------------------------------+
| Save area for CR (C) | 24+P+X+A+L+F+X+G | Save area for CR (C) | 24+P+A+L+X+F+Y+G
+---------------------------------------+ +---------------------------------------+
| Save area for TOC (T) | 24+P+X+A+L+F+X+G+C | Save area for TOC (T) | 24+P+A+L+X+F+Y+G+C
+---------------------------------------+ +---------------------------------------+
| Save area for LR (R) | 24+P+X+A+L+F+X+G+C+T | 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 ();
......
...@@ -3550,6 +3550,7 @@ ...@@ -3550,6 +3550,7 @@
(use (match_dup 2)) (use (match_dup 2))
(use (match_dup 3)) (use (match_dup 3))
(clobber (match_dup 4)) (clobber (match_dup 4))
(clobber (match_dup 5))
(clobber (reg:DF 76))])] (clobber (reg:DF 76))])]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT" "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
" "
...@@ -3557,6 +3558,7 @@ ...@@ -3557,6 +3558,7 @@
operands[2] = force_reg (SImode, GEN_INT (0x43300000)); operands[2] = force_reg (SImode, GEN_INT (0x43300000));
operands[3] = force_reg (DFmode, rs6000_float_const (\"4503601774854144\", DFmode)); operands[3] = force_reg (DFmode, rs6000_float_const (\"4503601774854144\", DFmode));
operands[4] = gen_reg_rtx (SImode); operands[4] = gen_reg_rtx (SImode);
operands[5] = gen_reg_rtx (Pmode);
}") }")
(define_insn "*floatsidf2_internal" (define_insn "*floatsidf2_internal"
...@@ -3565,10 +3567,11 @@ ...@@ -3565,10 +3567,11 @@
(use (match_operand:SI 2 "gpc_reg_operand" "r")) (use (match_operand:SI 2 "gpc_reg_operand" "r"))
(use (match_operand:DF 3 "gpc_reg_operand" "f")) (use (match_operand:DF 3 "gpc_reg_operand" "f"))
(clobber (match_operand:SI 4 "gpc_reg_operand" "=r")) (clobber (match_operand:SI 4 "gpc_reg_operand" "=r"))
(clobber (match_operand:SI 5 "gpc_reg_operand" "=b"))
(clobber (reg:DF 76))] (clobber (reg:DF 76))]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT" "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
"#" "#"
[(set_attr "length" "20")]) [(set_attr "length" "24")])
(define_split (define_split
[(set (match_operand:DF 0 "gpc_reg_operand" "") [(set (match_operand:DF 0 "gpc_reg_operand" "")
...@@ -3576,28 +3579,31 @@ ...@@ -3576,28 +3579,31 @@
(use (match_operand:SI 2 "gpc_reg_operand" "")) (use (match_operand:SI 2 "gpc_reg_operand" ""))
(use (match_operand:DF 3 "gpc_reg_operand" "")) (use (match_operand:DF 3 "gpc_reg_operand" ""))
(clobber (match_operand:SI 4 "gpc_reg_operand" "")) (clobber (match_operand:SI 4 "gpc_reg_operand" ""))
(clobber (match_operand:SI 5 "gpc_reg_operand" ""))
(clobber (reg:DF 76))] (clobber (reg:DF 76))]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT" "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
[(set (match_dup 4) [(set (match_dup 4)
(xor:SI (match_dup 1) (xor:SI (match_dup 1)
(match_dup 5))) (match_dup 6)))
(set (match_dup 6) (set (match_dup 5)
(unspec [(match_dup 4) ;; low word (unspec [(const_int 0)] 11))
(reg:SI 1)] 11)) (set (match_dup 7)
(set (match_dup 6) (unspec [(match_dup 4)
(unspec [(match_dup 2) ;; high word (match_dup 5)] 12)) ;; low word
(reg:SI 1) (set (match_dup 7)
(match_dup 6)] 12)) (unspec [(match_dup 2)
(match_dup 5)
(match_dup 7)] 13)) ;; high word
(set (match_dup 0) (set (match_dup 0)
(unspec [(match_dup 6) (unspec [(match_dup 7)
(reg:SI 1)] 13)) (match_dup 5)] 14))
(set (match_dup 0) (set (match_dup 0)
(minus:DF (match_dup 0) (minus:DF (match_dup 0)
(match_dup 3)))] (match_dup 3)))]
" "
{ {
operands[5] = GEN_INT (0x80000000); operands[6] = GEN_INT (0x80000000);
operands[6] = gen_rtx (REG, DFmode, FPMEM_REGNUM); operands[7] = gen_rtx (REG, DFmode, FPMEM_REGNUM);
}") }")
(define_expand "floatunssidf2" (define_expand "floatunssidf2"
...@@ -3605,12 +3611,14 @@ ...@@ -3605,12 +3611,14 @@
(unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" ""))) (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "")))
(use (match_dup 2)) (use (match_dup 2))
(use (match_dup 3)) (use (match_dup 3))
(clobber (match_dup 4))
(clobber (reg:DF 76))])] (clobber (reg:DF 76))])]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT" "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
" "
{ {
operands[2] = force_reg (SImode, GEN_INT (0x43300000)); operands[2] = force_reg (SImode, GEN_INT (0x43300000));
operands[3] = force_reg (DFmode, rs6000_float_const (\"4503599627370496\", DFmode)); operands[3] = force_reg (DFmode, rs6000_float_const (\"4503599627370496\", DFmode));
operands[4] = gen_reg_rtx (Pmode);
}") }")
(define_insn "*floatunssidf2_internal" (define_insn "*floatunssidf2_internal"
...@@ -3618,84 +3626,135 @@ ...@@ -3618,84 +3626,135 @@
(unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r"))) (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "r")))
(use (match_operand:SI 2 "gpc_reg_operand" "r")) (use (match_operand:SI 2 "gpc_reg_operand" "r"))
(use (match_operand:DF 3 "gpc_reg_operand" "f")) (use (match_operand:DF 3 "gpc_reg_operand" "f"))
(clobber (match_operand:SI 4 "gpc_reg_operand" "=b"))
(clobber (reg:DF 76))] (clobber (reg:DF 76))]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT" "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
"#" "#"
[(set_attr "length" "16")]) [(set_attr "length" "20")])
(define_split (define_split
[(set (match_operand:DF 0 "gpc_reg_operand" "") [(set (match_operand:DF 0 "gpc_reg_operand" "")
(unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" ""))) (unsigned_float:DF (match_operand:SI 1 "gpc_reg_operand" "")))
(use (match_operand:SI 2 "gpc_reg_operand" "")) (use (match_operand:SI 2 "gpc_reg_operand" ""))
(use (match_operand:DF 3 "gpc_reg_operand" "")) (use (match_operand:DF 3 "gpc_reg_operand" ""))
(clobber (match_operand:SI 4 "gpc_reg_operand" "=b"))
(clobber (reg:DF 76))] (clobber (reg:DF 76))]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT" "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
[(set (match_dup 4) [(set (match_dup 4)
(unspec [(match_dup 1) ;; low word (unspec [(const_int 0)] 11))
(reg:SI 1)] 11)) (set (match_dup 5)
(set (match_dup 4) (unspec [(match_dup 1)
(unspec [(match_dup 2) ;; high word (match_dup 4)] 12)) ;; low word
(reg:SI 1) (set (match_dup 5)
(reg:DF 76)] 12)) (unspec [(match_dup 2)
(match_dup 4)
(match_dup 5)] 13)) ;; high word
(set (match_dup 0) (set (match_dup 0)
(unspec [(match_dup 4) (unspec [(match_dup 5)
(reg:SI 1)] 13)) (reg:SI 1)] 14))
(set (match_dup 0) (set (match_dup 0)
(minus:DF (match_dup 0) (minus:DF (match_dup 0)
(match_dup 3)))] (match_dup 3)))]
"operands[4] = gen_rtx (REG, DFmode, FPMEM_REGNUM);") "operands[5] = gen_rtx (REG, DFmode, FPMEM_REGNUM);")
;; Load up scratch register with base address + offset if needed
(define_insn "*floatsidf2_loadaddr"
[(set (match_operand:SI 0 "gpc_reg_operand" "=b")
(unspec [(const_int 0)] 11))]
"TARGET_HARD_FLOAT"
"*
{
if (rs6000_fpmem_offset > 32760)
{
rtx xop[3];
xop[0] = operands[0];
xop[1] = (frame_pointer_needed) ? frame_pointer_rtx : stack_pointer_rtx;
xop[2] = GEN_INT ((rs6000_fpmem_offset >> 16) & 0xffff);
output_asm_insn (\"{cau %0,%2(%1)|addis %0,%1,%2}\", xop);
}
else if (rs6000_fpmem_offset < 0)
abort ();
;; Note, we list r1 in the unspec, so that the optimizer is not tempted to optimize return \"\";
;; around an alloca call (the memory address is constructed directly from r1). }"
[(set_attr "length" "4")])
(define_insn "*floatsidf2_store1" (define_insn "*floatsidf2_store1"
[(set (reg:DF 76) [(set (reg:DF 76)
(unspec [(match_operand:SI 0 "gpc_reg_operand" "r") (unspec [(match_operand:SI 0 "gpc_reg_operand" "r")
(reg:SI 1)] 11))] (match_operand:SI 1 "gpc_reg_operand" "r")] 12))]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT" "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
"* "*
{ {
operands[1] = gen_rtx (MEM, SImode, rtx indx;
if (rs6000_fpmem_offset > 32760)
indx = operands[1];
else if (frame_pointer_needed)
indx = frame_pointer_rtx;
else
indx = stack_pointer_rtx;
operands[2] = gen_rtx (MEM, SImode,
gen_rtx (PLUS, Pmode, gen_rtx (PLUS, Pmode,
stack_pointer_rtx, indx,
GEN_INT (rs6000_fpmem_offset GEN_INT ((rs6000_fpmem_offset & 0xffff)
+ ((WORDS_BIG_ENDIAN != 0) * 4)))); + ((WORDS_BIG_ENDIAN != 0) * 4))));
return \"{st|stw} %0,%1\"; return \"{st|stw} %0,%2\";
}" }"
[(set_attr "type" "store")]) [(set_attr "type" "store")])
(define_insn "*floatsidf2_store2" (define_insn "*floatsidf2_store2"
[(set (reg:DF 76) [(set (reg:DF 76)
(unspec [(match_operand:SI 0 "gpc_reg_operand" "r") (unspec [(match_operand:SI 0 "gpc_reg_operand" "r")
(reg:SI 1) (match_operand:SI 1 "gpc_reg_operand" "r")
(reg:DF 76)] 12))] (reg:DF 76)] 13))]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT" "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
"* "*
{ {
operands[1] = gen_rtx (MEM, SImode, rtx indx;
if (rs6000_fpmem_offset > 32760)
indx = operands[1];
else if (frame_pointer_needed)
indx = frame_pointer_rtx;
else
indx = stack_pointer_rtx;
operands[2] = gen_rtx (MEM, SImode,
gen_rtx (PLUS, Pmode, gen_rtx (PLUS, Pmode,
stack_pointer_rtx, indx,
GEN_INT (rs6000_fpmem_offset GEN_INT ((rs6000_fpmem_offset & 0xffff)
+ ((WORDS_BIG_ENDIAN == 0) * 4)))); + ((WORDS_BIG_ENDIAN == 0) * 4))));
return \"{st|stw} %0,%1\"; return \"{st|stw} %0,%2\";
}" }"
[(set_attr "type" "store")]) [(set_attr "type" "store")])
(define_insn "*floatsidf2_load" (define_insn "*floatsidf2_load"
[(set (match_operand:DF 0 "gpc_reg_operand" "=f") [(set (match_operand:DF 0 "gpc_reg_operand" "=f")
(unspec [(reg:DF 76) (unspec [(reg:DF 76)
(reg:SI 1)] 13))] (match_operand:SI 1 "gpc_reg_operand" "b")] 14))]
"! TARGET_POWERPC64 && TARGET_HARD_FLOAT" "! TARGET_POWERPC64 && TARGET_HARD_FLOAT"
"* "*
{ {
operands[1] = gen_rtx (MEM, SImode, rtx indx;
if (rs6000_fpmem_offset > 32760)
indx = operands[1];
else if (frame_pointer_needed)
indx = frame_pointer_rtx;
else
indx = stack_pointer_rtx;
operands[2] = gen_rtx (MEM, SImode,
gen_rtx (PLUS, Pmode, gen_rtx (PLUS, Pmode,
stack_pointer_rtx, indx,
GEN_INT (rs6000_fpmem_offset))); GEN_INT (rs6000_fpmem_offset)));
return \"lfd %0,%1\"; return \"lfd %0,%2\";
}" }"
[(set_attr "type" "fpload")]) [(set_attr "type" "fpload")])
...@@ -3703,7 +3762,8 @@ ...@@ -3703,7 +3762,8 @@
[(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "") [(parallel [(set (match_operand:SI 0 "gpc_reg_operand" "")
(fix:SI (match_operand:DF 1 "gpc_reg_operand" ""))) (fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))
(clobber (match_dup 2)) (clobber (match_dup 2))
(clobber (match_dup 3))])] (clobber (match_dup 3))
(clobber (match_dup 4))])]
"TARGET_HARD_FLOAT" "TARGET_HARD_FLOAT"
" "
{ {
...@@ -3715,13 +3775,15 @@ ...@@ -3715,13 +3775,15 @@
} }
operands[2] = gen_reg_rtx (DImode); operands[2] = gen_reg_rtx (DImode);
operands[3] = gen_rtx (REG, DImode, FPMEM_REGNUM); operands[3] = gen_reg_rtx (Pmode);
operands[4] = gen_rtx (REG, DImode, FPMEM_REGNUM);
}") }")
(define_insn "*fix_truncdfsi2_internal" (define_insn "*fix_truncdfsi2_internal"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r") [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))) (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
(clobber (match_operand:DI 2 "gpc_reg_operand" "=f")) (clobber (match_operand:DI 2 "gpc_reg_operand" "=f"))
(clobber (match_operand:SI 3 "gpc_reg_operand" "=b"))
(clobber (reg:DI 76))] (clobber (reg:DI 76))]
"TARGET_HARD_FLOAT" "TARGET_HARD_FLOAT"
"#" "#"
...@@ -3731,17 +3793,20 @@ ...@@ -3731,17 +3793,20 @@
[(set (match_operand:SI 0 "gpc_reg_operand" "") [(set (match_operand:SI 0 "gpc_reg_operand" "")
(fix:SI (match_operand:DF 1 "gpc_reg_operand" "f"))) (fix:SI (match_operand:DF 1 "gpc_reg_operand" "f")))
(clobber (match_operand:DI 2 "gpc_reg_operand" "")) (clobber (match_operand:DI 2 "gpc_reg_operand" ""))
(clobber (match_operand:SI 3 "gpc_reg_operand" ""))
(clobber (reg:DI 76))] (clobber (reg:DI 76))]
"TARGET_HARD_FLOAT" "TARGET_HARD_FLOAT"
[(set (match_dup 2) [(set (match_dup 2)
(sign_extend:DI (fix:SI (match_operand:DF 1 "gpc_reg_operand" "")))) (sign_extend:DI (fix:SI (match_operand:DF 1 "gpc_reg_operand" ""))))
(set (match_dup 3) (set (match_dup 3)
(unspec [(const_int 0)] 11))
(set (match_dup 4)
(unspec [(match_dup 2) (unspec [(match_dup 2)
(reg:SI 1)] 14)) (match_dup 3)] 15))
(set (match_operand:SI 0 "gpc_reg_operand" "") (set (match_operand:SI 0 "gpc_reg_operand" "")
(unspec [(match_dup 3) (unspec [(match_dup 4)
(reg:SI 1)] 15))] (match_dup 3)] 16))]
"operands[3] = gen_rtx (REG, DImode, FPMEM_REGNUM);") "operands[4] = gen_rtx (REG, DImode, FPMEM_REGNUM);")
(define_insn "*fctiwz" (define_insn "*fctiwz"
[(set (match_operand:DI 0 "gpc_reg_operand" "=f") [(set (match_operand:DI 0 "gpc_reg_operand" "=f")
...@@ -3753,32 +3818,51 @@ ...@@ -3753,32 +3818,51 @@
(define_insn "*fix_truncdfsi2_store" (define_insn "*fix_truncdfsi2_store"
[(set (reg:DI 76) [(set (reg:DI 76)
(unspec [(match_operand:DI 0 "gpc_reg_operand" "f") (unspec [(match_operand:DI 0 "gpc_reg_operand" "f")
(reg:SI 1)] 14))] (match_operand:SI 1 "gpc_reg_operand" "b")] 15))]
"(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT" "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT"
"* "*
{ {
operands[1] = gen_rtx (MEM, DFmode, rtx indx;
if (rs6000_fpmem_offset > 32760)
indx = operands[1];
else if (frame_pointer_needed)
indx = frame_pointer_rtx;
else
indx = stack_pointer_rtx;
operands[2] = gen_rtx (MEM, DFmode,
gen_rtx (PLUS, Pmode, gen_rtx (PLUS, Pmode,
stack_pointer_rtx, indx,
GEN_INT (rs6000_fpmem_offset))); GEN_INT ((rs6000_fpmem_offset & 0xffff))));
return \"stfd %0,%1\"; return \"stfd %0,%2\";
}" }"
[(set_attr "type" "fpstore")]) [(set_attr "type" "fpstore")])
(define_insn "*fix_truncdfsi2_load" (define_insn "*fix_truncdfsi2_load"
[(set (match_operand:SI 0 "gpc_reg_operand" "=r") [(set (match_operand:SI 0 "gpc_reg_operand" "=r")
(unspec [(reg:DI 76) (unspec [(reg:DI 76)
(reg:SI 1)] 15))] (match_operand:SI 1 "gpc_reg_operand" "b")] 16))]
"(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT" "(TARGET_POWER2 || TARGET_POWERPC) && TARGET_HARD_FLOAT"
"* "*
{ {
operands[1] = gen_rtx (MEM, DFmode, rtx indx;
if (rs6000_fpmem_offset > 32760)
indx = operands[1];
else if (frame_pointer_needed)
indx = frame_pointer_rtx;
else
indx = stack_pointer_rtx;
operands[2] = gen_rtx (MEM, DFmode,
gen_rtx (PLUS, Pmode, gen_rtx (PLUS, Pmode,
stack_pointer_rtx, indx,
GEN_INT (rs6000_fpmem_offset + ((WORDS_BIG_ENDIAN) ? 4 : 0)))); GEN_INT ((rs6000_fpmem_offset & 0xffff)
+ ((WORDS_BIG_ENDIAN) ? 4 : 0))));
return \"{l|lwz} %0,%1\"; return \"{l|lwz} %0,%2\";
}" }"
[(set_attr "type" "load")]) [(set_attr "type" "load")])
......
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