summaryrefslogtreecommitdiff
path: root/gcc/config/pa
diff options
context:
space:
mode:
authorYamaArashi <shadow962@live.com>2016-02-11 01:12:34 -0800
committerYamaArashi <shadow962@live.com>2016-02-11 01:12:34 -0800
commitb84b6b23fa58beb5674b37279742eb65461ca076 (patch)
treea85da124cbf9f888a31b750ede3a832c2c6b96aa /gcc/config/pa
parent23e2a17097740709d4466a802e03992116b12900 (diff)
delete irrelevant configs
Diffstat (limited to 'gcc/config/pa')
-rwxr-xr-xgcc/config/pa/ee.asm261
-rwxr-xr-xgcc/config/pa/ee_fp.asm274
-rwxr-xr-xgcc/config/pa/lib1funcs.asm1146
-rwxr-xr-xgcc/config/pa/lib2funcs.asm74
-rwxr-xr-xgcc/config/pa/pa-gas.h22
-rwxr-xr-xgcc/config/pa/pa-hiux.h26
-rwxr-xr-xgcc/config/pa/pa-hpux.h49
-rwxr-xr-xgcc/config/pa/pa-hpux10.h89
-rwxr-xr-xgcc/config/pa/pa-hpux11.h98
-rwxr-xr-xgcc/config/pa/pa-hpux7.h37
-rwxr-xr-xgcc/config/pa/pa-hpux9.h31
-rwxr-xr-xgcc/config/pa/pa-oldas.h22
-rwxr-xr-xgcc/config/pa/pa-osf.h42
-rwxr-xr-xgcc/config/pa/pa-pro-end.h42
-rwxr-xr-xgcc/config/pa/pa-pro.h79
-rwxr-xr-xgcc/config/pa/pa.c6491
-rwxr-xr-xgcc/config/pa/pa.h2601
-rwxr-xr-xgcc/config/pa/pa.md5729
-rwxr-xr-xgcc/config/pa/pa1.h28
-rwxr-xr-xgcc/config/pa/rtems.h31
-rwxr-xr-xgcc/config/pa/t-dce-thr5
-rwxr-xr-xgcc/config/pa/t-pa18
-rwxr-xr-xgcc/config/pa/t-pro38
-rwxr-xr-xgcc/config/pa/x-pa3
-rwxr-xr-xgcc/config/pa/x-pa-hpux4
-rwxr-xr-xgcc/config/pa/xm-pa.h62
-rwxr-xr-xgcc/config/pa/xm-pahpux.h61
-rwxr-xr-xgcc/config/pa/xm-papro.h58
28 files changed, 0 insertions, 17421 deletions
diff --git a/gcc/config/pa/ee.asm b/gcc/config/pa/ee.asm
deleted file mode 100755
index 787bda7..0000000
--- a/gcc/config/pa/ee.asm
+++ /dev/null
@@ -1,261 +0,0 @@
-; Subroutines for out of line prologues and epilogues on for the HPPA
-; Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
-
-; This file is part of GNU CC.
-
-; GNU CC is free software; you can redistribute it and/or modify
-; it under the terms of the GNU General Public License as published by
-; the Free Software Foundation; either version 2, or (at your option)
-; any later version.
-
-; GNU CC is distributed in the hope that it will be useful,
-; but WITHOUT ANY WARRANTY; without even the implied warranty of
-; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-; GNU General Public License for more details.
-
-; You should have received a copy of the GNU General Public License
-; along with GNU CC; see the file COPYING. If not, write to
-; the Free Software Foundation, 59 Temple Place - Suite 330,
-; Boston, MA 02111-1307, USA.
-
- .SPACE $PRIVATE$
- .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
- .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
- .SPACE $TEXT$
- .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
- .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
- .SUBSPA $MILLICODE$,QUAD=0,ALIGN=8,ACCESS=44,SORT=8
-
-; This is an out-of-line prologue.
-;
-; It performs the following operations:
-;
-; * Saves the return pointer at sp - 20
-;
-; * Creates a new stack frame (sp'), size of the frame is passed in %r21
-;
-; * The old stack pointer is saved at sp (frame pointer version only).
-;
-; * Saves grs (passed in low 16 bits of %r22 into the stack frame
-; at sp' + local_fsize (passed in %r19).
-;
-; * Saves frs (passed in high 16 bits of %r22) into the stack
-; frame at sp' + local_fsize (passed in %r19).
-;
-; * Sets up a frame pointer (in %r3) (frame pointer version only).
-;
-; * Returns to the instruction _immediately_ after the call to
-; this function.
-
- .SPACE $TEXT$
- .SUBSPA $MILLICODE$
- .EXPORT __outline_prologue,MILLICODE
- .align 32
-__outline_prologue
- .PROC
- .CALLINFO FRAME=0,NO_CALLS
- .ENTRY
- copy %r30,%r20
-
- ; Subtract 4 from our return pointer so that we return to
- ; the right location.
- ldo -4(%r31),%r31
-
- ; Save off %r2
- stw %r2,-20(0,%r30)
-
- ; Make our new frame.
- add %r21,%r30,%r30
-
- ; Add in local_fsize to our frame pointer so we do register
- ; saves into the right place
- add %r20,%r19,%r20
-
- ; %r22 tells us what registers we need to save. The upper half
- ; is for fp registers, the lower half for integer registers.
- ; We put the lower half in %r1 and the upper half into %r22
- ; for later use.
- extru %r22,31,16,%r1
- extrs %r22,15,16,%r22
-
- ; %r1 now olds a value 0-18 which corresponds to the number
- ; of grs we need to save. We need to reverse that value so
- ; we can just into the table and straight-line execute to the
- ; end of the gr saves.
- comb,= %r0,%r1,L$0000
- subi 18,%r1,%r1
- blr,n %r1,%r0
- b,n L$0000
- stws,ma %r18,4(0,%r20)
- nop
- stws,ma %r17,4(0,%r20)
- nop
- stws,ma %r16,4(0,%r20)
- nop
- stws,ma %r15,4(0,%r20)
- nop
- stws,ma %r14,4(0,%r20)
- nop
- stws,ma %r13,4(0,%r20)
- nop
- stws,ma %r12,4(0,%r20)
- nop
- stws,ma %r11,4(0,%r20)
- nop
- stws,ma %r10,4(0,%r20)
- nop
- stws,ma %r9,4(0,%r20)
- nop
- stws,ma %r8,4(0,%r20)
- nop
- stws,ma %r7,4(0,%r20)
- nop
- stws,ma %r6,4(0,%r20)
- nop
- stws,ma %r5,4(0,%r20)
- nop
- stws,ma %r4,4(0,%r20)
- nop
- stws,ma %r3,4(0,%r20)
- nop
-L$0000
- ; All gr saves are done. Align the temporary frame pointer and
- ; do the fr saves.
- ldo 7(%r20),%r20
- depi 0,31,3,%r20
-
- comb,= %r0,%r22,L$0001
- subi 21,%r22,%r22
- blr,n %r22,%r0
- b,n L$0001
- fstws,ma %fr21,8(0,%r20)
- nop
- fstws,ma %fr20,8(0,%r20)
- nop
- fstws,ma %fr19,8(0,%r20)
- nop
- fstws,ma %fr18,8(0,%r20)
- nop
- fstws,ma %fr17,8(0,%r20)
- nop
- fstws,ma %fr16,8(0,%r20)
- nop
- fstws,ma %fr15,8(0,%r20)
- nop
- fstws,ma %fr14,8(0,%r20)
- nop
- fstws,ma %fr13,8(0,%r20)
- nop
- fstws,ma %fr12,8(0,%r20)
- nop
-L$0001
- ; Return
- bv,n 0(%r31)
- .EXIT
- .PROCEND
-
-
-
- .EXPORT __outline_epilogue,MILLICODE
- .align 32
-__outline_epilogue
- .PROC
- .CALLINFO FRAME=0,NO_CALLS
- .ENTRY
- ; Get our original stack pointer and put it in %r20
- sub %r30,%r21,%r20
-
- ; Subtract 4 from our return pointer so that we return to
- ; the right location.
- ldo -4(%r31),%r31
-
- ; Reload %r2
- ldw -20(0,%r20),%r2
-
- ; Add in local_fsize (%r19) to the frame pointer to find
- ; the saved registers.
- add %r20,%r19,%r20
-
- ; %r22 tells us what registers we need to restore. The upper half
- ; is for fp registers, the lower half for integer registers.
- ; We put the lower half in %r1 and the upper half into %r22
- ; for later use.
- extru %r22,31,16,%r1
- extrs %r22,15,16,%r22
-
- ; %r1 now olds a value 0-18 which corresponds to the number
- ; of grs we need to restore. We need to reverse that value so
- ; we can just into the table and straight-line execute to the
- ; end of the gr restore.
- comb,= %r0,%r1,L$0004
- subi 18,%r1,%r1
- blr,n %r1,%r0
- b,n L$0004
- ldws,ma 4(0,%r20),%r18
- nop
- ldws,ma 4(0,%r20),%r17
- nop
- ldws,ma 4(0,%r20),%r16
- nop
- ldws,ma 4(0,%r20),%r15
- nop
- ldws,ma 4(0,%r20),%r14
- nop
- ldws,ma 4(0,%r20),%r13
- nop
- ldws,ma 4(0,%r20),%r12
- nop
- ldws,ma 4(0,%r20),%r11
- nop
- ldws,ma 4(0,%r20),%r10
- nop
- ldws,ma 4(0,%r20),%r9
- nop
- ldws,ma 4(0,%r20),%r8
- nop
- ldws,ma 4(0,%r20),%r7
- nop
- ldws,ma 4(0,%r20),%r6
- nop
- ldws,ma 4(0,%r20),%r5
- nop
- ldws,ma 4(0,%r20),%r4
- nop
- ldws,ma 4(0,%r20),%r3
- nop
-L$0004
- ; All gr restore are done. Align the temporary frame pointer and
- ; do the fr restore.
- ldo 7(%r20),%r20
- depi 0,31,3,%r20
-
- comb,= %r0,%r22,L$0005
- subi 21,%r22,%r22
- blr,n %r22,%r0
- b,n L$0005
- fldws,ma 8(0,%r20),%fr21
- nop
- fldws,ma 8(0,%r20),%fr20
- nop
- fldws,ma 8(0,%r20),%fr19
- nop
- fldws,ma 8(0,%r20),%fr18
- nop
- fldws,ma 8(0,%r20),%fr17
- nop
- fldws,ma 8(0,%r20),%fr16
- nop
- fldws,ma 8(0,%r20),%fr15
- nop
- fldws,ma 8(0,%r20),%fr14
- nop
- fldws,ma 8(0,%r20),%fr13
- nop
- fldws,ma 8(0,%r20),%fr12
- nop
-L$0005
- ; Return and deallocate our frame.
- bv 0(%r31)
- sub %r30,%r21,%r30
- .EXIT
- .PROCEND
diff --git a/gcc/config/pa/ee_fp.asm b/gcc/config/pa/ee_fp.asm
deleted file mode 100755
index ef040cf..0000000
--- a/gcc/config/pa/ee_fp.asm
+++ /dev/null
@@ -1,274 +0,0 @@
-; Subroutines for out of line prologues and epilogues on for the HPPA
-; Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
-
-; This file is part of GNU CC.
-
-; GNU CC is free software; you can redistribute it and/or modify
-; it under the terms of the GNU General Public License as published by
-; the Free Software Foundation; either version 2, or (at your option)
-; any later version.
-
-; GNU CC is distributed in the hope that it will be useful,
-; but WITHOUT ANY WARRANTY; without even the implied warranty of
-; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-; GNU General Public License for more details.
-
-; You should have received a copy of the GNU General Public License
-; along with GNU CC; see the file COPYING. If not, write to
-; the Free Software Foundation, 59 Temple Place - Suite 330,
-; Boston, MA 02111-1307, USA.
-
- .SPACE $PRIVATE$
- .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
- .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
- .SPACE $TEXT$
- .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
- .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
- .SUBSPA $MILLICODE$,QUAD=0,ALIGN=8,ACCESS=44,SORT=8
-
-
-; This is an out-of-line prologue.
-;
-; It performs the following operations:
-;
-; * Saves the return pointer at sp - 20
-;
-; * Creates a new stack frame (sp'), size of the frame is passed in %r21
-;
-; * The old stack pointer is saved at sp (frame pointer version only).
-;
-; * Saves grs (passed in low 16 bits of %r22 into the stack frame
-; at sp' + local_fsize (passed in %r19).
-;
-; * Saves frs (passed in high 16 bits of %r22) into the stack
-; frame at sp' + local_fsize (passed in %r19).
-;
-; * Sets up a frame pointer (in %r3) (frame pointer version only).
-;
-; * Returns to the instruction _immediately_ after the call to
-; this function.
-
- .SPACE $TEXT$
- .SUBSPA $MILLICODE$
- .EXPORT __outline_prologue_fp,MILLICODE
- .align 32
-__outline_prologue_fp
- .PROC
- .CALLINFO FRAME=0,NO_CALLS
- .ENTRY
- copy %r30,%r20
-
- ; Subtract 4 from our return pointer so that we return to
- ; the right location.
- ldo -4(%r31),%r31
-
- ; Save off %r2
- stw %r2,-20(0,%r30)
-
- ; Make our new frame.
- add %r21,%r30,%r30
-
- ; Save our old stack pointer.
- stw %r20,0(0,%r20)
-
- ; Add in local_fsize to our frame pointer so we do register
- ; saves into the right place
- add %r20,%r19,%r20
-
- ; %r22 tells us what registers we need to save. The upper half
- ; is for fp registers, the lower half for integer registers.
- ; We put the lower half in %r1 and the upper half into %r22
- ; for later use.
- extru %r22,31,16,%r1
- extrs %r22,15,16,%r22
-
- ; %r1 now olds a value 0-18 which corresponds to the number
- ; of grs we need to save. We need to reverse that value so
- ; we can just into the table and straight-line execute to the
- ; end of the gr saves.
- comb,= %r0,%r1,L$0002
- subi 18,%r1,%r1
- blr,n %r1,%r0
- b,n L$0002
- stws,ma %r18,4(0,%r20)
- nop
- stws,ma %r17,4(0,%r20)
- nop
- stws,ma %r16,4(0,%r20)
- nop
- stws,ma %r15,4(0,%r20)
- nop
- stws,ma %r14,4(0,%r20)
- nop
- stws,ma %r13,4(0,%r20)
- nop
- stws,ma %r12,4(0,%r20)
- nop
- stws,ma %r11,4(0,%r20)
- nop
- stws,ma %r10,4(0,%r20)
- nop
- stws,ma %r9,4(0,%r20)
- nop
- stws,ma %r8,4(0,%r20)
- nop
- stws,ma %r7,4(0,%r20)
- nop
- stws,ma %r6,4(0,%r20)
- nop
- stws,ma %r5,4(0,%r20)
- nop
- stws,ma %r4,4(0,%r20)
- nop
- stws,ma %r3,4(0,%r20)
- nop
-L$0002
- ; All gr saves are done. Align the temporary frame pointer and
- ; do the fr saves.
- ldo 7(%r20),%r20
- depi 0,31,3,%r20
-
- comb,= %r0,%r22,L$0003
- subi 21,%r22,%r22
- blr,n %r22,%r0
- b,n L$0003
- fstws,ma %fr21,8(0,%r20)
- nop
- fstws,ma %fr20,8(0,%r20)
- nop
- fstws,ma %fr19,8(0,%r20)
- nop
- fstws,ma %fr18,8(0,%r20)
- nop
- fstws,ma %fr17,8(0,%r20)
- nop
- fstws,ma %fr16,8(0,%r20)
- nop
- fstws,ma %fr15,8(0,%r20)
- nop
- fstws,ma %fr14,8(0,%r20)
- nop
- fstws,ma %fr13,8(0,%r20)
- nop
- fstws,ma %fr12,8(0,%r20)
- nop
-L$0003
- ; Return, setting up a frame pointer in the delay slot
- bv 0(%r31)
- sub %r30,%r21,%r3
- .EXIT
- .PROCEND
-
-
-; This is an out-of-line epilogue. It's operation is basically the reverse
-; of the out-of-line prologue.
-
- .EXPORT __outline_epilogue_fp,MILLICODE
- .align 32
-__outline_epilogue_fp
- .PROC
- .CALLINFO FRAME=0,NO_CALLS
- .ENTRY
- ; Make a copy of our frame pointer into %r20
- copy %r3,%r20
-
- ; Subtract 4 from our return pointer so that we return to
- ; the right location.
- ldo -4(%r31),%r31
-
- ; Reload %r2
- ; First save off %r2
- ldw -20(0,%r20),%r2
-
- ; Load our old stack pointer, save it in %r21.
- ldw 0(0,%r20),%r21
-
- ; Add in local_fsize (%r19) to the frame pointer to find
- ; the saved registers.
- add %r20,%r19,%r20
-
- ; %r22 tells us what registers we need to restore. The upper half
- ; is for fp registers, the lower half for integer registers.
- ; We put the lower half in %r1 and the upper half into %r22
- ; for later use.
- extru %r22,31,16,%r1
- extrs %r22,15,16,%r22
-
- ; %r1 now olds a value 0-18 which corresponds to the number
- ; of grs we need to restore. We need to reverse that value so
- ; we can just into the table and straight-line execute to the
- ; end of the gr restore.
- comb,= %r0,%r1,L$0006
- subi 18,%r1,%r1
- blr,n %r1,%r0
- b,n L$0006
- ldws,ma 4(0,%r20),%r18
- nop
- ldws,ma 4(0,%r20),%r17
- nop
- ldws,ma 4(0,%r20),%r16
- nop
- ldws,ma 4(0,%r20),%r15
- nop
- ldws,ma 4(0,%r20),%r14
- nop
- ldws,ma 4(0,%r20),%r13
- nop
- ldws,ma 4(0,%r20),%r12
- nop
- ldws,ma 4(0,%r20),%r11
- nop
- ldws,ma 4(0,%r20),%r10
- nop
- ldws,ma 4(0,%r20),%r9
- nop
- ldws,ma 4(0,%r20),%r8
- nop
- ldws,ma 4(0,%r20),%r7
- nop
- ldws,ma 4(0,%r20),%r6
- nop
- ldws,ma 4(0,%r20),%r5
- nop
- ldws,ma 4(0,%r20),%r4
- nop
- ldws,ma 4(0,%r20),%r3
- nop
-L$0006
- ; All gr restore are done. Align the temporary frame pointer and
- ; do the fr restore.
- ldo 7(%r20),%r20
- depi 0,31,3,%r20
-
- comb,= %r0,%r22,L$0007
- subi 21,%r22,%r22
- blr,n %r22,%r0
- b,n L$0007
- fldws,ma 8(0,%r20),%fr21
- nop
- fldws,ma 8(0,%r20),%fr20
- nop
- fldws,ma 8(0,%r20),%fr19
- nop
- fldws,ma 8(0,%r20),%fr18
- nop
- fldws,ma 8(0,%r20),%fr17
- nop
- fldws,ma 8(0,%r20),%fr16
- nop
- fldws,ma 8(0,%r20),%fr15
- nop
- fldws,ma 8(0,%r20),%fr14
- nop
- fldws,ma 8(0,%r20),%fr13
- nop
- fldws,ma 8(0,%r20),%fr12
- nop
-L$0007
- ; Return and deallocate our frame.
- bv 0(%r31)
- copy %r21,%r30
- .EXIT
- .PROCEND
-
-
diff --git a/gcc/config/pa/lib1funcs.asm b/gcc/config/pa/lib1funcs.asm
deleted file mode 100755
index 95eb75e..0000000
--- a/gcc/config/pa/lib1funcs.asm
+++ /dev/null
@@ -1,1146 +0,0 @@
-; Low level integer divide, multiply, remainder, etc routines for the HPPA.
-; Copyright (C) 1995 Free Software Foundation, Inc.
-
-; This file is part of GNU CC.
-
-; GNU CC is free software; you can redistribute it and/or modify
-; it under the terms of the GNU General Public License as published by
-; the Free Software Foundation; either version 2, or (at your option)
-; any later version.
-
-; In addition to the permissions in the GNU General Public License, the
-; Free Software Foundation gives you unlimited permission to link the
-; compiled version of this file with other programs, and to distribute
-; those programs without any restriction coming from the use of this
-; file. (The General Public License restrictions do apply in other
-; respects; for example, they cover modification of the file, and
-; distribution when not linked into another program.)
-
-; GNU CC is distributed in the hope that it will be useful,
-; but WITHOUT ANY WARRANTY; without even the implied warranty of
-; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-; GNU General Public License for more details.
-
-; You should have received a copy of the GNU General Public License
-; along with GNU CC; see the file COPYING. If not, write to
-; the Free Software Foundation, 59 Temple Place - Suite 330,
-; Boston, MA 02111-1307, USA.
-
-#ifdef L_dyncall
- .space $TEXT$
- .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
- .export $$dyncall
-$$dyncall
- .proc
- .callinfo frame=0,no_calls
- .entry
- bb,>=,n %r22,30,L$1 ; branch if not plabel address
- depi 0,31,2,%r22 ; clear the two least significant bits
- ldw 4(%sr0,%r22),%r19 ; load new LTP value
- ldw 0(%sr0,%r22),%r22 ; load address of target
-L$1 ldsid (%sr0,%r22),%r1 ; get the "space ident" selected by r22
- mtsp %r1,%sr0 ; move that space identifier into sr0
- be 0(%sr0,%r22) ; branch to the real target
- stw %r2,-24(%sr0,%r30) ; save return address into frame marker
- .exit
- .procend
-#endif
-
-
-#ifdef L_multiply
-#define op0 %r26
-#define op1 %r25
-#define res %r29
-#define ret %r31
-#define tmp %r1
- .space $TEXT$
- .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
- .align 4
- .export $$mulU
- .export $$mulI
-$$mulU
-$$mulI
- .proc
- .callinfo frame=0,no_calls
- .entry
- addi,tr 0,%r0,res ; clear out res, skip next insn
-L$loop zdep op1,26,27,op1 ; shift up op1 by 5
-L$lo zdep op0,30,5,tmp ; extract next 5 bits and shift up
- blr tmp,%r0
- extru op0,26,27,op0 ; shift down op0 by 5
-L$0 comib,<> 0,op0,L$lo
- zdep op1,26,27,op1 ; shift up op1 by 5
- bv %r0(ret)
- nop
-L$1 b L$loop
- addl op1,res,res
- nop
- nop
-L$2 b L$loop
- sh1addl op1,res,res
- nop
- nop
-L$3 sh1addl op1,op1,tmp ; 3x
- b L$loop
- addl tmp,res,res
- nop
-L$4 b L$loop
- sh2addl op1,res,res
- nop
- nop
-L$5 sh2addl op1,op1,tmp ; 5x
- b L$loop
- addl tmp,res,res
- nop
-L$6 sh1addl op1,op1,tmp ; 3x
- b L$loop
- sh1addl tmp,res,res
- nop
-L$7 zdep op1,28,29,tmp ; 8x
- sub tmp,op1,tmp ; 7x
- b L$loop
- addl tmp,res,res
-L$8 b L$loop
- sh3addl op1,res,res
- nop
- nop
-L$9 sh3addl op1,op1,tmp ; 9x
- b L$loop
- addl tmp,res,res
- nop
-L$10 sh2addl op1,op1,tmp ; 5x
- b L$loop
- sh1addl tmp,res,res
- nop
-L$11 sh2addl op1,op1,tmp ; 5x
- sh1addl tmp,op1,tmp ; 11x
- b L$loop
- addl tmp,res,res
-L$12 sh1addl op1,op1,tmp ; 3x
- b L$loop
- sh2addl tmp,res,res
- nop
-L$13 sh1addl op1,op1,tmp ; 3x
- sh2addl tmp,op1,tmp ; 13x
- b L$loop
- addl tmp,res,res
-L$14 zdep op1,28,29,tmp ; 8x
- sub tmp,op1,tmp ; 7x
- b L$loop
- sh1addl tmp,res,res
-L$15 zdep op1,27,28,tmp ; 16x
- sub tmp,op1,tmp ; 15x
- b L$loop
- addl tmp,res,res
-L$16 zdep op1,27,28,tmp ; 16x
- b L$loop
- addl tmp,res,res
- nop
-L$17 zdep op1,27,28,tmp ; 16x
- addl tmp,op1,tmp ; 17x
- b L$loop
- addl tmp,res,res
-L$18 sh3addl op1,op1,tmp ; 9x
- b L$loop
- sh1addl tmp,res,res
- nop
-L$19 sh3addl op1,op1,tmp ; 9x
- sh1addl tmp,op1,tmp ; 19x
- b L$loop
- addl tmp,res,res
-L$20 sh2addl op1,op1,tmp ; 5x
- b L$loop
- sh2addl tmp,res,res
- nop
-L$21 sh2addl op1,op1,tmp ; 5x
- sh2addl tmp,op1,tmp ; 21x
- b L$loop
- addl tmp,res,res
-L$22 sh2addl op1,op1,tmp ; 5x
- sh1addl tmp,op1,tmp ; 11x
- b L$loop
- sh1addl tmp,res,res
-L$23 sh1addl op1,op1,tmp ; 3x
- sh3addl tmp,res,res ; += 8x3
- b L$loop
- sub res,op1,res ; -= x
-L$24 sh1addl op1,op1,tmp ; 3x
- b L$loop
- sh3addl tmp,res,res ; += 8x3
- nop
-L$25 sh2addl op1,op1,tmp ; 5x
- sh2addl tmp,tmp,tmp ; 25x
- b L$loop
- addl tmp,res,res
-L$26 sh1addl op1,op1,tmp ; 3x
- sh2addl tmp,op1,tmp ; 13x
- b L$loop
- sh1addl tmp,res,res ; += 2x13
-L$27 sh1addl op1,op1,tmp ; 3x
- sh3addl tmp,tmp,tmp ; 27x
- b L$loop
- addl tmp,res,res
-L$28 zdep op1,28,29,tmp ; 8x
- sub tmp,op1,tmp ; 7x
- b L$loop
- sh2addl tmp,res,res ; += 4x7
-L$29 sh1addl op1,op1,tmp ; 3x
- sub res,tmp,res ; -= 3x
- b L$foo
- zdep op1,26,27,tmp ; 32x
-L$30 zdep op1,27,28,tmp ; 16x
- sub tmp,op1,tmp ; 15x
- b L$loop
- sh1addl tmp,res,res ; += 2x15
-L$31 zdep op1,26,27,tmp ; 32x
- sub tmp,op1,tmp ; 31x
-L$foo b L$loop
- addl tmp,res,res
- .exit
- .procend
-#endif
-
-
-#ifdef L_divU
-#define dividend %r26
-#define divisor %r25
-#define tmp %r1
-#define quotient %r29
-#define ret %r31
- .space $TEXT$
- .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
- .align 4
- .export $$divU
-$$divU
- .proc
- .callinfo frame=0,no_calls
- .entry
- comb,< divisor,0,L$largedivisor
- sub %r0,divisor,%r1 ; clear cy as side-effect
- ds %r0,%r1,%r0
- addc dividend,dividend,dividend
- ds %r0,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,quotient
- ds %r1,divisor,%r1
- bv 0(ret)
- addc quotient,quotient,quotient
-L$largedivisor
- comclr,<< dividend,divisor,quotient
- ldi 1,quotient
- bv,n 0(ret)
- .exit
- .procend
-#endif
-
-
-#ifdef L_remU
-#define dividend %r26
-#define divisor %r25
-#define quotient %r29
-#define tmp %r1
-#define ret %r31
- .space $TEXT$
- .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
- .align 4
- .export $$remU
-$$remU
- .proc
- .callinfo frame=0,no_calls
- .entry
- comb,< divisor,0,L$largedivisor
- sub %r0,divisor,%r1 ; clear cy as side-effect
- ds %r0,%r1,%r0
- addc dividend,dividend,dividend
- ds %r0,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,quotient
- ds %r1,divisor,%r1
- comclr,>= %r1,%r0,%r0
- addl %r1,divisor,%r1
- bv 0(ret)
- copy %r1,quotient
-L$largedivisor
- sub,>>= dividend,divisor,quotient
- copy dividend,quotient
- bv,n 0(ret)
- .exit
- .procend
-#endif
-
-
-#ifdef L_divI
-#define dividend %r26
-#define divisor %r25
-#define quotient %r29
-#define tmp %r1
-#define ret %r31
- .space $TEXT$
- .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
- .align 4
- .export $$divI
-$$divI
- .proc
- .callinfo frame=0,no_calls
- .entry
- xor dividend,divisor,quotient ; result sign
- comclr,>= divisor,%r0,%r0 ; get absolute values
- sub %r0,divisor,divisor
- comclr,>= dividend,%r0,%r0
- sub %r0,dividend,dividend
-
- comb,< divisor,0,L$largedivisor
- sub %r0,divisor,%r1 ; clear cy as side-effect
- ds %r0,%r1,%r0
- addc dividend,dividend,dividend
- ds %r0,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- comclr,>= %r1,%r0,%r0
- addl %r1,divisor,%r1
- comclr,>= quotient,%r0,%r0 ; skip of no need to negate
- sub %r0,dividend,dividend
- bv 0(ret)
- copy dividend,quotient
-L$largedivisor
- comclr,<< dividend,divisor,quotient
- ldi 1,quotient
- bv,n 0(ret)
- .exit
- .procend
-#endif
-
-
-#ifdef L_remI
-#define dividend %r26
-#define divisor %r25
-#define quotient %r29
-#define tmp %r1
-#define ret %r31
- .space $TEXT$
- .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
- .align 4
- .export $$remI
-$$remI
- .proc
- .callinfo frame=0,no_calls
- .entry
- xor dividend,%r0,quotient ; result sign
- comclr,>= divisor,%r0,%r0 ; get absolute values
- sub %r0,divisor,divisor
- comclr,>= dividend,%r0,%r0
- sub %r0,dividend,dividend
-
- comb,< divisor,0,L$largedivisor
- sub %r0,divisor,%r1 ; clear cy as side-effect
- ds %r0,%r1,%r0
- addc dividend,dividend,dividend
- ds %r0,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- ds %r1,divisor,%r1
- addc dividend,dividend,dividend
- comclr,>= %r1,%r0,%r0
- addl %r1,divisor,%r1
- comclr,>= quotient,%r0,%r0 ; skip of no need to negate
- sub %r0,%r1,%r1
- bv 0(ret)
- copy %r1,quotient
-L$largedivisor
- sub,>>= dividend,divisor,quotient
- copy dividend,quotient
- bv,n 0(ret)
- .exit
- .procend
-#endif
-
-
-#if defined (L_divU_3) && !defined (SMALL_LIB)
-#undef L_divU_3
-#define dividend %r26
-#define divisor %r25
-#define tmp %r1
-#define result %r29
-#define ret %r31
- .space $TEXT$
- .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
- .align 4
- .export $$divU_3
-$$divU_3
- .proc
- .callinfo frame=0,no_calls
- .entry
- sh2add %r26,%r26,%r29 ; r29 = lo(101 x r)
- shd %r0,%r26,30,%r1 ; r1 = hi(100 x r)
- addc %r1,%r0,%r1 ; r1 = hi(101 x r)
-; r in r1,,r29
- zdep %r29,27,28,%r25 ; r25 = lo(10000 x r)
- add %r25,%r29,%r25 ; r25 = lo(10001 x r)
- shd %r1,%r29,28,%r29 ; r29 = hi(10000 x r)
- addc %r29,%r1,%r29 ; r29 = hi(10001 x r)
-; r in r29,,r25
- zdep %r25,23,24,%r1 ; r1 = lo(100000000 x r)
- add %r1,%r25,%r1 ; r1 = lo(100000001 x r)
- shd %r29,%r25,24,%r25 ; r25 = hi(100000000 x r)
- addc %r25,%r29,%r25 ; r25 = hi(100000001 x r)
-; r in r25,,r1
- zdep %r1,15,16,%r29
- add %r29,%r1,%r29
- shd %r25,%r1,16,%r1
- addc %r1,%r25,%r1
-; r in r1,,r29
- sh1add %r29,%r26,%r0 ; r0 = lo(10 x r) + dividend
- shd %r1,%r29,31,%r29 ; r29 = hi(10 x r)
- addc %r29,%r0,%r29
- bv 0(ret)
- extru %r29,30,31,result
- .exit
- .procend
-#endif
-
-
-#if defined (L_divU_5) && !defined (SMALL_LIB)
-#undef L_divU_5
-#define dividend %r26
-#define divisor %r25
-#define tmp %r1
-#define result %r29
-#define ret %r31
- .space $TEXT$
- .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
- .align 4
- .export $$divU_5
-$$divU_5
- .proc
- .callinfo frame=0,no_calls
- .entry
- sh1add %r26,%r26,%r29 ; r29 = lo(11 x r)
- shd %r0,%r26,31,%r1 ; r1 = hi(10 x r)
- addc %r1,%r0,%r1 ; r1 = hi(11 x r)
-; r in r1,,r29
- zdep %r29,27,28,%r25 ; r25 = lo(10000 x r)
- add %r25,%r29,%r25 ; r25 = lo(10001 x r)
- shd %r1,%r29,28,%r29 ; r29 = hi(10000 x r)
- addc %r29,%r1,%r29 ; r29 = hi(10001 x r)
-; r in r29,,r25
- zdep %r25,23,24,%r1 ; r1 = lo(100000000 x r)
- add %r1,%r25,%r1 ; r1 = lo(100000001 x r)
- shd %r29,%r25,24,%r25 ; r25 = hi(100000000 x r)
- addc %r25,%r29,%r25 ; r25 = hi(100000001 x r)
-; r in r25,,r1
- zdep %r1,15,16,%r29
- add %r29,%r1,%r29
- shd %r25,%r1,16,%r1
- addc %r1,%r25,%r1
-; r in r1,,r29
- sh2add %r29,%r26,%r0 ; r0 = lo(1000 x r) + dividend
- shd %r1,%r29,30,%r29 ; r29 = hi(1000 x r)
- addc %r29,%r0,%r29
- bv 0(ret)
- extru %r29,29,30,result
- .exit
- .procend
-#endif
-
-
-#if defined (L_divU_6) && !defined (SMALL_LIB)
-#undef L_divU_6
-#define dividend %r26
-#define divisor %r25
-#define tmp %r1
-#define result %r29
-#define ret %r31
- .space $TEXT$
- .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
- .align 4
- .export $$divU_6
-$$divU_6
- .proc
- .callinfo frame=0,no_calls
- .entry
- sh2add %r26,%r26,%r29 ; r29 = lo(101 x r)
- shd %r0,%r26,30,%r1 ; r1 = hi(100 x r)
- addc %r1,%r0,%r1 ; r1 = hi(101 x r)
-; r in r1,,r29
- zdep %r29,27,28,%r25 ; r25 = lo(10000 x r)
- add %r25,%r29,%r25 ; r25 = lo(10001 x r)
- shd %r1,%r29,28,%r29 ; r29 = hi(10000 x r)
- addc %r29,%r1,%r29 ; r29 = hi(10001 x r)
-; r in r29,,r25
- zdep %r25,23,24,%r1 ; r1 = lo(100000000 x r)
- add %r1,%r25,%r1 ; r1 = lo(100000001 x r)
- shd %r29,%r25,24,%r25 ; r25 = hi(100000000 x r)
- addc %r25,%r29,%r25 ; r25 = hi(100000001 x r)
-; r in r25,,r1
- zdep %r1,15,16,%r29
- add %r29,%r1,%r29
- shd %r25,%r1,16,%r1
- addc %r1,%r25,%r1
-; r in r1,,r29
- sh1add %r29,%r26,%r0 ; r0 = lo(10 x r) + dividend
- shd %r1,%r29,31,%r29 ; r29 = hi(10 x r)
- addc %r29,%r0,%r29
- bv 0(ret)
- extru %r29,29,30,result
- .exit
- .procend
-#endif
-
-
-#if defined (L_divU_9) && !defined (SMALL_LIB)
-#undef L_divU_9
-#define dividend %r26
-#define divisor %r25
-#define tmp %r1
-#define result %r29
-#define ret %r31
- .space $TEXT$
- .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
- .align 4
- .export $$divU_9
-$$divU_9
- .proc
- .callinfo frame=0,no_calls
- .entry
- zdep %r26,28,29,%r29
- sub %r29,%r26,%r29
- shd 0,%r26,29,%r1
- subb %r1,0,%r1 /* 111 */
-
- zdep %r29,25,26,%r25
- add %r25,%r29,%r25
- shd %r1,%r29,26,%r29
- addc %r29,%r1,%r29 /* 111000111 */
-
- sh3add %r25,%r26,%r1
- shd %r29,%r25,29,%r25
- addc %r25,0,%r25 /* 111000111001 */
-
- zdep %r1,16,17,%r29
- sub %r29,%r1,%r29
- shd %r25,%r1,17,%r1
- subb %r1,%r25,%r1 /* 111000111000111000111000111 */
-
- sh3add %r29,%r26,%r0
- shd %r1,%r29,29,%r29
- addc %r29,0,%r29 /* 111000111000111000111000111001 */
- bv 0(ret)
- extru %r29,30,31,result
- .exit
- .procend
-#endif
-
-
-#if defined (L_divU_10) && !defined (SMALL_LIB)
-#undef L_divU_10
-#define dividend %r26
-#define divisor %r25
-#define tmp %r1
-#define result %r29
-#define ret %r31
- .space $TEXT$
- .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
- .align 4
- .export $$divU_10
-$$divU_10
- .proc
- .callinfo frame=0,no_calls
- .entry
- sh1add %r26,%r26,%r29 ; r29 = lo(11 x r)
- shd %r0,%r26,31,%r1 ; r1 = hi(10 x r)
- addc %r1,%r0,%r1 ; r1 = hi(11 x r)
-; r in r1,,r29
- zdep %r29,27,28,%r25 ; r25 = lo(10000 x r)
- add %r25,%r29,%r25 ; r25 = lo(10001 x r)
- shd %r1,%r29,28,%r29 ; r29 = hi(10000 x r)
- addc %r29,%r1,%r29 ; r29 = hi(10001 x r)
-; r in r29,,r25
- zdep %r25,23,24,%r1 ; r1 = lo(100000000 x r)
- add %r1,%r25,%r1 ; r1 = lo(100000001 x r)
- shd %r29,%r25,24,%r25 ; r25 = hi(100000000 x r)
- addc %r25,%r29,%r25 ; r25 = hi(100000001 x r)
-; r in r25,,r1
- zdep %r1,15,16,%r29
- add %r29,%r1,%r29
- shd %r25,%r1,16,%r1
- addc %r1,%r25,%r1
-; r in r1,,r29
- sh2add %r29,%r26,%r0 ; r0 = lo(1000 x r) + dividend
- shd %r1,%r29,30,%r29 ; r29 = hi(1000 x r)
- addc %r29,%r0,%r29
- bv 0(ret)
- extru %r29,28,29,result
- .exit
- .procend
-#endif
-
-
-#if defined (L_divU_12) && !defined (SMALL_LIB)
-#undef L_divU_12
-#define dividend %r26
-#define divisor %r25
-#define tmp %r1
-#define result %r29
-#define ret %r31
- .space $TEXT$
- .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
- .align 4
- .export $$divU_12
-$$divU_12
- .proc
- .callinfo frame=0,no_calls
- .entry
- sh2add %r26,%r26,%r29 ; r29 = lo(101 x r)
- shd %r0,%r26,30,%r1 ; r1 = hi(100 x r)
- addc %r1,%r0,%r1 ; r1 = hi(101 x r)
-; r in r1,,r29
- zdep %r29,27,28,%r25 ; r25 = lo(10000 x r)
- add %r25,%r29,%r25 ; r25 = lo(10001 x r)
- shd %r1,%r29,28,%r29 ; r29 = hi(10000 x r)
- addc %r29,%r1,%r29 ; r29 = hi(10001 x r)
-; r in r29,,r25
- zdep %r25,23,24,%r1 ; r1 = lo(100000000 x r)
- add %r1,%r25,%r1 ; r1 = lo(100000001 x r)
- shd %r29,%r25,24,%r25 ; r25 = hi(100000000 x r)
- addc %r25,%r29,%r25 ; r25 = hi(100000001 x r)
-; r in r25,,r1
- zdep %r1,15,16,%r29
- add %r29,%r1,%r29
- shd %r25,%r1,16,%r1
- addc %r1,%r25,%r1
-; r in r1,,r29
- sh1add %r29,%r26,%r0 ; r0 = lo(10 x r) + dividend
- shd %r1,%r29,31,%r29 ; r29 = hi(10 x r)
- addc %r29,%r0,%r29
- bv 0(ret)
- extru %r29,28,29,result
- .exit
- .procend
-#endif
-
-
-#ifdef L_divU_3
- .space $TEXT$
- .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
- .align 4
- .export $$divU_3
-$$divU_3
- .proc
- .callinfo frame=0,no_calls
- .entry
- b $$divU
- ldi 3,%r25
- .exit
- .procend
- .import $$divU,MILLICODE
-#endif
-
-#ifdef L_divU_5
- .space $TEXT$
- .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
- .align 4
- .export $$divU_5
-$$divU_5
- .proc
- .callinfo frame=0,no_calls
- .entry
- b $$divU
- ldi 5,%r25
- .exit
- .procend
- .import $$divU,MILLICODE
-#endif
-
-#ifdef L_divU_6
- .space $TEXT$
- .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
- .align 4
- .export $$divU_6
-$$divU_6
- .proc
- .callinfo frame=0,no_calls
- .entry
- b $$divU
- ldi 6,%r25
- .exit
- .procend
- .import $$divU,MILLICODE
-#endif
-
-#ifdef L_divU_7
- .space $TEXT$
- .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
- .align 4
- .export $$divU_7
-$$divU_7
- .proc
- .callinfo frame=0,no_calls
- .entry
- b $$divU
- ldi 7,%r25
- .exit
- .procend
- .import $$divU,MILLICODE
-#endif
-
-#ifdef L_divU_9
- .space $TEXT$
- .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
- .align 4
- .export $$divU_9
-$$divU_9
- .proc
- .callinfo frame=0,no_calls
- .entry
- b $$divU
- ldi 9,%r25
- .exit
- .procend
- .import $$divU,MILLICODE
-#endif
-
-#ifdef L_divU_10
- .space $TEXT$
- .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
- .align 4
- .export $$divU_10
-$$divU_10
- .proc
- .callinfo frame=0,no_calls
- .entry
- b $$divU
- ldi 10,%r25
- .exit
- .procend
- .import $$divU,MILLICODE
-#endif
-
-#ifdef L_divU_12
- .space $TEXT$
- .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
- .align 4
- .export $$divU_12
-$$divU_12
- .proc
- .callinfo frame=0,no_calls
- .entry
- b $$divU
- ldi 12,%r25
- .exit
- .procend
- .import $$divU,MILLICODE
-#endif
-
-#ifdef L_divU_14
- .space $TEXT$
- .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
- .align 4
- .export $$divU_14
-$$divU_14
- .proc
- .callinfo frame=0,no_calls
- .entry
- b $$divU
- ldi 14,%r25
- .exit
- .procend
- .import $$divU,MILLICODE
-#endif
-
-#ifdef L_divU_15
- .space $TEXT$
- .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
- .align 4
- .export $$divU_15
-$$divU_15
- .proc
- .callinfo frame=0,no_calls
- .entry
- b $$divU
- ldi 15,%r25
- .exit
- .procend
- .import $$divU,MILLICODE
-#endif
-
-#ifdef L_divI_3
- .space $TEXT$
- .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
- .align 4
- .export $$divI_3
-$$divI_3
- .proc
- .callinfo frame=0,no_calls
- .entry
- b $$divI
- ldi 3,%r25
- .exit
- .procend
- .import $$divI,MILLICODE
-#endif
-
-#ifdef L_divI_5
- .space $TEXT$
- .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
- .align 4
- .export $$divI_5
-$$divI_5
- .proc
- .callinfo frame=0,no_calls
- .entry
- b $$divI
- ldi 5,%r25
- .exit
- .procend
- .import $$divI,MILLICODE
-#endif
-
-#ifdef L_divI_6
- .space $TEXT$
- .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
- .align 4
- .export $$divI_6
-$$divI_6
- .proc
- .callinfo frame=0,no_calls
- .entry
- b $$divI
- ldi 6,%r25
- .exit
- .procend
- .import $$divI,MILLICODE
-#endif
-
-#ifdef L_divI_7
- .space $TEXT$
- .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
- .align 4
- .export $$divI_7
-$$divI_7
- .proc
- .callinfo frame=0,no_calls
- .entry
- b $$divI
- ldi 7,%r25
- .exit
- .procend
- .import $$divI,MILLICODE
-#endif
-
-#ifdef L_divI_9
- .space $TEXT$
- .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
- .align 4
- .export $$divI_9
-$$divI_9
- .proc
- .callinfo frame=0,no_calls
- .entry
- b $$divI
- ldi 9,%r25
- .exit
- .procend
- .import $$divI,MILLICODE
-#endif
-
-#ifdef L_divI_10
- .space $TEXT$
- .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
- .align 4
- .export $$divI_10
-$$divI_10
- .proc
- .callinfo frame=0,no_calls
- .entry
- b $$divI
- ldi 10,%r25
- .exit
- .procend
- .import $$divI,MILLICODE
-#endif
-
-#ifdef L_divI_12
- .space $TEXT$
- .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
- .align 4
- .export $$divI_12
-$$divI_12
- .proc
- .callinfo frame=0,no_calls
- .entry
- b $$divI
- ldi 12,%r25
- .exit
- .procend
- .import $$divI,MILLICODE
-#endif
-
-#ifdef L_divI_14
- .space $TEXT$
- .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
- .align 4
- .export $$divI_14
-$$divI_14
- .proc
- .callinfo frame=0,no_calls
- .entry
- b $$divI
- ldi 14,%r25
- .exit
- .procend
- .import $$divI,MILLICODE
-#endif
-
-#ifdef L_divI_15
- .space $TEXT$
- .subspa $MILLICODE$,quad=0,align=8,access=0x2c,sort=8
- .align 4
- .export $$divI_15
-$$divI_15
- .proc
- .callinfo frame=0,no_calls
- .entry
- b $$divI
- ldi 15,%r25
- .exit
- .procend
- .import $$divI,MILLICODE
-#endif
diff --git a/gcc/config/pa/lib2funcs.asm b/gcc/config/pa/lib2funcs.asm
deleted file mode 100755
index cf57cbb..0000000
--- a/gcc/config/pa/lib2funcs.asm
+++ /dev/null
@@ -1,74 +0,0 @@
-; Subroutines for calling unbound dynamic functions from within GDB for HPPA.
-; Subroutines for out of line prologues and epilogues on for the HPPA
-; Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
-
-; This file is part of GNU CC.
-
-; GNU CC is free software; you can redistribute it and/or modify
-; it under the terms of the GNU General Public License as published by
-; the Free Software Foundation; either version 2, or (at your option)
-; any later version.
-
-; GNU CC is distributed in the hope that it will be useful,
-; but WITHOUT ANY WARRANTY; without even the implied warranty of
-; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-; GNU General Public License for more details.
-
-; In addition to the permissions in the GNU General Public License, the
-; Free Software Foundation gives you unlimited permission to link the
-; compiled version of this file with other programs, and to distribute
-; those programs without any restriction coming from the use of this
-; file. (The General Public License restrictions do apply in other
-; respects; for example, they cover modification of the file, and
-; distribution when not linked into another program.)
-
-; You should have received a copy of the GNU General Public License
-; along with GNU CC; see the file COPYING. If not, write to
-; the Free Software Foundation, 59 Temple Place - Suite 330,
-; Boston, MA 02111-1307, USA.
-
- .SPACE $PRIVATE$
- .SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
- .SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
- .SPACE $TEXT$
- .SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
- .SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
- .SUBSPA $MILLICODE$,QUAD=0,ALIGN=8,ACCESS=44,SORT=8
-
- .IMPORT $$dyncall,MILLICODE
-; gcc_compiled.:
- .SPACE $TEXT$
- .SUBSPA $CODE$
-
-; Simply call with the address of the desired import stub in %r22 and
-; arguments in the normal place (%r26-%r23 and stack slots).
-;
- .align 4
- .EXPORT __gcc_plt_call,ENTRY,PRIV_LEV=3,RTNVAL=GR
-__gcc_plt_call
- .PROC
- .CALLINFO
- .ENTRY
- ; Our return address comes in %r31, not %r2!
- stw %r31,-8(0,%r30)
-
- ; An inline version of dyncall so we don't have to worry
- ; about long calls to millicode, PIC and other complexities.
- bb,>=,n %r22,30,L$foo
- depi 0,31,2,%r22
- ldw 4(%r22),%r19
- ldw 0(%r22),%r22
-L$foo
- ldsid (%r22),%r1
- mtsp %r1,%sr0
- ble 0(%sr0,%r22)
- copy %r31,%r2
- ldw -8(0,%r30),%r2
-
- ; We're going to be returning to a stack address, so we
- ; need to do an intra-space return.
- ldsid (%rp),%r1
- mtsp %r1,%sr0
- be,n 0(%sr0,%rp)
- .EXIT
- .PROCEND
diff --git a/gcc/config/pa/pa-gas.h b/gcc/config/pa/pa-gas.h
deleted file mode 100755
index 4106b70..0000000
--- a/gcc/config/pa/pa-gas.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Definitions of target machine for GNU compiler, for HP-UX using GNU as.
- Copyright (C) 1996 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-#undef TARGET_DEFAULT
-#define TARGET_DEFAULT 0x88 /* TARGET_GAS + TARGET_JUMP_IN_DELAY */
diff --git a/gcc/config/pa/pa-hiux.h b/gcc/config/pa/pa-hiux.h
deleted file mode 100755
index f4be95b..0000000
--- a/gcc/config/pa/pa-hiux.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/* Definitions of target machine for GNU compiler, for HI-UX.
- Copyright (C) 1993, 1995, 1996 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-/* HIUX is just a HPUX variant. We can simply use the HPUX configuration
- for just about everything. */
-
-/* Predefines are the one noteworthy difference between HPUX and HIUX. */
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-Dhppa -DPWB -Dunix -D__H3050R -D__H3050RX -Asystem(unix) -Asystem(hiux) -Acpu(hppa) -Amachine(hppa)"
diff --git a/gcc/config/pa/pa-hpux.h b/gcc/config/pa/pa-hpux.h
deleted file mode 100755
index e001ebe..0000000
--- a/gcc/config/pa/pa-hpux.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* Definitions of target machine for GNU compiler, for HP-UX.
- Copyright (C) 1991, 1995, 1996 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-#undef TARGET_DEFAULT
-#define TARGET_DEFAULT 0
-
-/* Make GCC agree with types.h. */
-#undef SIZE_TYPE
-#undef PTRDIFF_TYPE
-
-#define SIZE_TYPE "unsigned int"
-#define PTRDIFF_TYPE "int"
-
-/* Like the default, except no -lg. */
-#undef LIB_SPEC
-#define LIB_SPEC "%{!shared:%{!p:%{!pg:-lc}}%{p: -L/lib/libp/ -lc}%{pg: -L/lib/libp/ -lc}}"
-
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-Dhppa -Dhp9000s800 -D__hp9000s800 -Dhp9k8 -DPWB -Dhpux -Dunix -Asystem(unix) -Asystem(hpux) -Acpu(hppa) -Amachine(hppa)"
-
-#undef LINK_SPEC
-#if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & 1)
-#define LINK_SPEC \
- "%{!mpa-risc-1-0:%{!shared:-L/lib/pa1.1 -L/usr/lib/pa1.1 }}%{mlinker-opt:-O} %{!shared:-u main} %{static:-a archive} %{g*:-a archive} %{shared:-b}"
-#else
-#define LINK_SPEC \
- "%{mlinker-opt:-O} %{!shared:-u main} %{static:-a archive} %{g*:-a archive} %{shared:-b}"
-#endif
-
-/* hpux8 and later have C++ compatible include files, so do not
- pretend they are `extern "C"'. */
-#define NO_IMPLICIT_EXTERN_C
diff --git a/gcc/config/pa/pa-hpux10.h b/gcc/config/pa/pa-hpux10.h
deleted file mode 100755
index e00c107..0000000
--- a/gcc/config/pa/pa-hpux10.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/* Definitions of target machine for GNU compiler, for HP PA-RISC 1.1
- Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
- Contributed by Tim Moore (moore@defmacro.cs.utah.edu)
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-/* We can debug dynamically linked executables on hpux9; we also want
- dereferencing of a NULL pointer to cause a SEGV. */
-#undef LINK_SPEC
-#if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & 1)
-#define LINK_SPEC \
- "%{!mpa-risc-1-0:%{!shared:-L/lib/pa1.1 -L/usr/lib/pa1.1 }} -z %{mlinker-opt:-O} %{!shared:-u main} %{static:-a archive} %{shared:-b}"
-#else
-#define LINK_SPEC \
- "-z %{mlinker-opt:-O} %{!shared:-u main} %{static:-a archive} %{shared:-b}"
-#endif
-
-/* Like the default, except no -lg. */
-#undef LIB_SPEC
-#define LIB_SPEC \
- "%{!shared:\
- %{!p:\
- %{!pg:\
- %{!threads:-lc}\
- %{threads:-lcma -lc_r}}\
- %{p: -L/lib/libp/ -lc}\
- %{pg: -L/lib/libp/ -lc}}}"
-
-/* The hpux10 assembler requires a .LEVEL pseudo-op at the start of
- the assembly file. */
-#undef ASM_FILE_START
-#define ASM_FILE_START(FILE) \
-do { \
- /* CYGNUS LOCAL pa8000/law */ \
- if (TARGET_PARISC_2_0) \
- fputs("\t.LEVEL 2.0\n", FILE); \
- else if (TARGET_SNAKE) \
- fputs("\t.LEVEL 1.1\n", FILE); \
- else \
- fputs("\t.LEVEL 1.0\n", FILE); \
- /* END CYGNUS LOCAL */ \
- fputs ("\t.SPACE $PRIVATE$\n\
-\t.SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31\n\
-\t.SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82\n\
-\t.SPACE $TEXT$\n\
-\t.SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44\n\
-\t.SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY\n\
-\t.IMPORT $global$,DATA\n\
-\t.IMPORT $$dyncall,MILLICODE\n", FILE);\
- if (profile_flag)\
- fprintf (FILE, "\t.IMPORT _mcount, CODE\n");\
- if (write_symbols != NO_DEBUG) \
- output_file_directive ((FILE), main_input_filename); \
- } while (0)
-
-/* Under hpux10, the normal location of the `ld' and `as' programs is the
- /usr/ccs/bin directory. */
-
-#ifndef CROSS_COMPILE
-#undef MD_EXEC_PREFIX
-#define MD_EXEC_PREFIX "/usr/ccs/bin/"
-#endif
-
-/* Under hpux10, the normal location of the various *crt*.o files is the
- /usr/ccs/lib directory. */
-
-#ifndef CROSS_COMPILE
-#undef MD_STARTFILE_PREFIX
-#define MD_STARTFILE_PREFIX "/usr/ccs/lib/"
-#endif
-
-/* hpux10 has the new HP assembler. It's still lousy, but it's a whole lot
- better than the assembler shipped with older versions of hpux. */
-#define NEW_HP_ASSEMBLER
diff --git a/gcc/config/pa/pa-hpux11.h b/gcc/config/pa/pa-hpux11.h
deleted file mode 100755
index 2959c5c..0000000
--- a/gcc/config/pa/pa-hpux11.h
+++ /dev/null
@@ -1,98 +0,0 @@
-/* CYGNUS LOCAL entire file hpux11/law */
-/* Definitions of target machine for GNU compiler, for HP PA-RISC 1.1
- Copyright (C) 1998 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-/* We can debug dynamically linked executables on hpux11; we also
- want dereferencing of a NULL pointer to cause a SEGV. */
-#undef LINK_SPEC
-#if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & 1)
-#define LINK_SPEC \
- "%{!mpa-risc-1-0:%{!shared:-L/lib/pa1.1 -L/usr/lib/pa1.1 }} -z %{mlinker-opt:-O} %{!shared:-u main} %{static:-a archive} %{shared:-b}"
-#else
-#define LINK_SPEC \
- "-z %{mlinker-opt:-O} %{!shared:-u main} %{static:-a archive} %{shared:-b}"
-#endif
-
-/* Like the default, except no -lg. */
-#undef LIB_SPEC
-#define LIB_SPEC \
- "%{!shared:\
- %{!p:\
- %{!pg:\
- %{!threads:-lc}\
- %{threads:-lcma -lc_r}}\
- %{p: -L/lib/libp/ -lc}\
- %{pg: -L/lib/libp/ -lc}}}"
-
-/* The hpux11 assembler requires a .LEVEL pseudo-op at the start of the
- assembly file. */
-#undef ASM_FILE_START
-#define ASM_FILE_START(FILE) \
-do { \
- /* CYGNUS LOCAL pa8000/law */ \
- if (TARGET_PARISC_2_0) \
- fputs("\t.LEVEL 2.0\n", FILE); \
- else if (TARGET_SNAKE) \
- fputs("\t.LEVEL 1.1\n", FILE); \
- else \
- fputs("\t.LEVEL 1.0\n", FILE); \
- /* END CYGNUS LOCAL */ \
- fputs ("\t.SPACE $PRIVATE$\n\
-\t.SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31\n\
-\t.SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82\n\
-\t.SPACE $TEXT$\n\
-\t.SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44\n\
-\t.SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY\n\
-\t.IMPORT $global$,DATA\n\
-\t.IMPORT $$dyncall,MILLICODE\n", FILE);\
- if (profile_flag)\
- fprintf (FILE, "\t.IMPORT _mcount, CODE\n");\
- if (write_symbols != NO_DEBUG) \
- output_file_directive ((FILE), main_input_filename); \
- } while (0)
-
-/* Under hpux11, the normal location of the `ld' and `as' programs is the
- /usr/ccs/bin directory. */
-
-#ifndef CROSS_COMPILE
-#undef MD_EXEC_PREFIX
-#define MD_EXEC_PREFIX "/usr/ccs/bin/"
-#endif
-
-/* Under hpux11 the normal location of the various *crt*.o files is the
- /usr/ccs/lib directory. */
-
-#ifndef CROSS_COMPILE
-#undef MD_STARTFILE_PREFIX
-#define MD_STARTFILE_PREFIX "/usr/ccs/lib/"
-#endif
-
-/* hpux11 has the new HP assembler. It's still lousy, but it's a whole lot
- better than the assembler shipped with older versions of hpux. */
-#define NEW_HP_ASSEMBLER
-
-/* Make GCC agree with types.h. */
-#undef SIZE_TYPE
-#undef PTRDIFF_TYPE
-
-#define SIZE_TYPE "long unsigned int"
-#define PTRDIFF_TYPE "long int"
-
-/* END CYGNUS LOCAL */
diff --git a/gcc/config/pa/pa-hpux7.h b/gcc/config/pa/pa-hpux7.h
deleted file mode 100755
index dc75ec2..0000000
--- a/gcc/config/pa/pa-hpux7.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/* Definitions of target machine for GNU compiler, for HP-UX.
- Copyright (C) 1991, 1995, 1996 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-#ifndef TARGET_DEFAULT
-#define TARGET_DEFAULT 0
-#endif
-
-/* Make GCC agree with types.h. */
-#undef SIZE_TYPE
-#undef PTRDIFF_TYPE
-
-#define SIZE_TYPE "unsigned int"
-#define PTRDIFF_TYPE "int"
-
-/* Like the default, except no -lg. */
-#undef LIB_SPEC
-#define LIB_SPEC "%{!p:%{!pg:-lc}}%{p: -L/lib/libp/ -lc}%{pg: -L/lib/libp/ -lc}"
-
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-Dhppa -Dhp9000s800 -D__hp9000s800 -Dhp9k8 -DPWB -Dhpux -Dunix -Asystem(unix) -Asystem(hpux) -Acpu(hppa) -Amachine(hppa)"
diff --git a/gcc/config/pa/pa-hpux9.h b/gcc/config/pa/pa-hpux9.h
deleted file mode 100755
index 8d039d2..0000000
--- a/gcc/config/pa/pa-hpux9.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Definitions of target machine for GNU compiler, for HP PA-RISC 1.1
- Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc.
- Contributed by Tim Moore (moore@defmacro.cs.utah.edu)
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-/* We can debug dynamically linked executables on hpux9; we also want
- dereferencing of a NULL pointer to cause a SEGV. */
-#undef LINK_SPEC
-#if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & 1)
-#define LINK_SPEC \
- "%{!mpa-risc-1-0:%{!shared:-L/lib/pa1.1 -L/usr/lib/pa1.1 }} -z %{mlinker-opt:-O} %{!shared:-u main} %{static:-a archive} %{shared:-b}"
-#else
-#define LINK_SPEC \
- "-z %{mlinker-opt:-O} %{!shared:-u main} %{static:-a archive} %{shared:-b}"
-#endif
diff --git a/gcc/config/pa/pa-oldas.h b/gcc/config/pa/pa-oldas.h
deleted file mode 100755
index 8ff741f..0000000
--- a/gcc/config/pa/pa-oldas.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Definitions of target machine for GNU compiler, for HP PA-RISC 1.1
- Copyright (C) 1991, 1996 Free Software Foundation, Inc.
- Contributed by Tim Moore (moore@defmacro.cs.utah.edu)
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-#define HP_FP_ARG_DESCRIPTOR_REVERSED
diff --git a/gcc/config/pa/pa-osf.h b/gcc/config/pa/pa-osf.h
deleted file mode 100755
index 047d20e..0000000
--- a/gcc/config/pa/pa-osf.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Definitions of target machine for GNU compiler, for HP PA-RISC 1.1
- Copyright (C) 1991, 1995, 1996 Free Software Foundation, Inc.
- Contributed by Tim Moore (moore@defmacro.cs.utah.edu)
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-#undef CPP_PREDEFINES
-#if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & 1)
-#define CPP_PREDEFINES "-Dhppa -Dunix -Dhp9000 -Dspectrum -DREVARGV -Dhp700 -DHP700 -Dparisc -D__pa_risc -DPARISC -DBYTE_MSF -DBIT_MSF -Asystem(unix) -Asystem(mach) -Acpu(hppa) -Amachine(hppa)"
-#else
-#define CPP_PREDEFINES "-Dhppa -Dhp9000s800 -D__hp9000s800 -Dhp9k8 -Dunix -Dhp9000 -Dhp800 -Dspectrum -DREVARGV -Dparisc -D__pa_risc -DPARISC -DBYTE_MSF -DBIT_MSF -Asystem(unix) -Asystem(mach) -Acpu(hppa) -Amachine(hppa)"
-#endif
-
-/* Don't default to pcc-struct-return, because gcc is the only compiler, and
- we want to retain compatibility with older gcc versions. */
-#define DEFAULT_PCC_STRUCT_RETURN 0
-
-/* OSF1 on the PA still uses 16bit wchar_t. */
-#undef WCHAR_TYPE
-#undef WCHAR_TYPE_SIZE
-
-#define WCHAR_TYPE "short unsigned int"
-#define WCHAR_TYPE_SIZE 16
-
-/* OSF1 wants to be different and use unsigned long as size_t. */
-#undef SIZE_TYPE
-#define SIZE_TYPE "long unsigned int"
diff --git a/gcc/config/pa/pa-pro-end.h b/gcc/config/pa/pa-pro-end.h
deleted file mode 100755
index de88036..0000000
--- a/gcc/config/pa/pa-pro-end.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/* Definitions of target machine for GNU compiler, for PRO.
- Copyright (C) 1996, 1997 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-/* Make GCC agree with types.h. */
-#undef SIZE_TYPE
-#undef PTRDIFF_TYPE
-
-#define SIZE_TYPE "unsigned int"
-#define PTRDIFF_TYPE "int"
-
-/* Like the default, except no -lg. */
-#undef LIB_SPEC
-#define LIB_SPEC "%{!p:%{!pg:-lc}}%{p: -L/lib/libp/ -lc}%{pg: -L/lib/libp/ -lc}"
-
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-Dhppa -DPWB -Acpu(hppa) -Amachine(hppa)"
-
-/* hpux8 and later have C++ compatible include files, so do not
- pretend they are `extern "C"'. */
-#define NO_IMPLICIT_EXTERN_C
-
-/* We don't want a crt0.o to get linked in automatically, we want the
- linker script to pull it in.
- */
-#define STARTFILE_SPEC ""
diff --git a/gcc/config/pa/pa-pro.h b/gcc/config/pa/pa-pro.h
deleted file mode 100755
index 2ec832b..0000000
--- a/gcc/config/pa/pa-pro.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/* Definitions of target machine for GNU compiler, for PRO.
- Copyright (C) 1994, 1995, 1996 Free Software Foundation, Inc.
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-/* Global constructor and destructor support. */
-/* Define the pseudo-ops used to switch to the .ctors and .dtors sections.
-
- Note that we want to give these sections the SHF_WRITE attribute
- because these sections will actually contain data (i.e. tables of
- addresses of functions in the current root executable or shared library
- file) and, in the case of a shared library, the relocatable addresses
- will have to be properly resolved/relocated (and then written into) by
- the dynamic linker when it actually attaches the given shared library
- to the executing process. */
-
-#define CTORS_SECTION_ASM_OP "\t.section\t\".ctors\",#alloc,#write"
-#define DTORS_SECTION_ASM_OP "\t.section\t\".dtors\",#alloc,#write"
-
-#define CTORS_SECTION_FUNCTION \
-void \
-ctors_section () \
-{ \
- if (in_section != in_ctors) \
- { \
- fprintf (asm_out_file, "%s\n", CTORS_SECTION_ASM_OP); \
- in_section = in_ctors; \
- } \
-}
-
-#define DTORS_SECTION_FUNCTION \
-void \
-dtors_section () \
-{ \
- if (in_section != in_dtors) \
- { \
- fprintf (asm_out_file, "%s\n", DTORS_SECTION_ASM_OP); \
- in_section = in_dtors; \
- } \
-}
-
-
-/* A C statement (sans semicolon) to output an element in the table of
- global destructors. */
-#define ASM_OUTPUT_DESTRUCTOR(FILE,NAME) \
- do { \
- dtors_section (); \
- fputs ("\t.word\t ", FILE); \
- assemble_name (FILE, NAME); \
- fputs ("\n", FILE); \
- } while (0)
-
-/* A C statement (sans semicolon) to output an element in the table of
- global constructors. */
-#define ASM_OUTPUT_CONSTRUCTOR(FILE,NAME) \
- do { \
- ctors_section (); \
- fputs ("\t.word\t ", FILE); \
- assemble_name (FILE, NAME); \
- fputs ("\n", FILE); \
- } while (0)
-
-/* JUMP_IN_DELAY + PORTABLE_RUNTIME + GAS + NO_SPACE_REGS + SOFT_FLOAT */
-#define TARGET_DEFAULT (4 + 8 + 64 + 128 + 256)
diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c
deleted file mode 100755
index de7f698..0000000
--- a/gcc/config/pa/pa.c
+++ /dev/null
@@ -1,6491 +0,0 @@
-/* Subroutines for insn-output.c for HPPA.
- Copyright (C) 1992, 93-98, 1999 Free Software Foundation, Inc.
- Contributed by Tim Moore (moore@cs.utah.edu), based on sparc.c
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-#include "config.h"
-#include "system.h"
-
-#include "rtl.h"
-#include "regs.h"
-#include "hard-reg-set.h"
-#include "real.h"
-#include "insn-config.h"
-#include "conditions.h"
-#include "insn-flags.h"
-#include "output.h"
-#include "insn-attr.h"
-#include "flags.h"
-#include "tree.h"
-#include "reload.h"
-#include "c-tree.h"
-#include "expr.h"
-#include "obstack.h"
-#include "toplev.h"
-
-static void restore_unscaled_index_insn_codes PROTO((rtx));
-static void record_unscaled_index_insn_codes PROTO((rtx));
-static void pa_combine_instructions PROTO((rtx));
-static int pa_can_combine_p PROTO((rtx, rtx, rtx, int, rtx, rtx, rtx));
-static int forward_branch_p PROTO((rtx));
-static int shadd_constant_p PROTO((int));
-
-/* Save the operands last given to a compare for use when we
- generate a scc or bcc insn. */
-
-rtx hppa_compare_op0, hppa_compare_op1;
-enum cmp_type hppa_branch_type;
-
-/* Which cpu we are scheduling for. */
-enum processor_type pa_cpu;
-
-/* String to hold which cpu we are scheduling for. */
-char *pa_cpu_string;
-
-/* Set by the FUNCTION_PROFILER macro. */
-int hp_profile_labelno;
-
-/* Counts for the number of callee-saved general and floating point
- registers which were saved by the current function's prologue. */
-static int gr_saved, fr_saved;
-
-/* Whether or not the current function uses an out-of-line prologue
- and epilogue. */
-static int out_of_line_prologue_epilogue;
-
-static rtx find_addr_reg ();
-
-/* Keep track of the number of bytes we have output in the CODE subspaces
- during this compilation so we'll know when to emit inline long-calls. */
-
-unsigned int total_code_bytes;
-
-/* Variables to handle plabels that we discover are necessary at assembly
- output time. They are output after the current function. */
-
-struct deferred_plabel
-{
- rtx internal_label;
- char *name;
-} *deferred_plabels = 0;
-int n_deferred_plabels = 0;
-
-/* Array indexed by INSN_UIDs holding the INSN_CODE of an insn which
- uses an unscaled indexed address before delay slot scheduling. */
-static int *unscaled_index_insn_codes;
-
-/* Upper bound for the array. */
-static int max_unscaled_index_insn_codes_uid;
-
-void
-override_options ()
-{
- /* Default to 7100 scheduling. If the 7100LC scheduling ever
- gets reasonably tuned, it should be the default since that
- what most PAs sold now are. */
- if (pa_cpu_string == NULL
- || ! strcmp (pa_cpu_string, "7100"))
- {
- pa_cpu_string = "7100";
- pa_cpu = PROCESSOR_7100;
- }
- else if (! strcmp (pa_cpu_string, "700"))
- {
- pa_cpu_string = "700";
- pa_cpu = PROCESSOR_700;
- }
- else if (! strcmp (pa_cpu_string, "7100LC"))
- {
- pa_cpu_string = "7100LC";
- pa_cpu = PROCESSOR_7100LC;
- }
- else if (! strcmp (pa_cpu_string, "7200"))
- {
- pa_cpu_string = "7200";
- pa_cpu = PROCESSOR_7200;
- }
- /* CYGNUS LOCAL PA8000/law */
- else if (! strcmp (pa_cpu_string, "8000"))
- {
- pa_cpu_string = "8000";
- pa_cpu = PROCESSOR_8000;
- }
- else
- {
- warning ("Unknown -mschedule= option (%s).\nValid options are 700, 7100 and 7100LC, 7200 and 8000\n", pa_cpu_string);
- }
- /* END CYGNUS LOCAL */
-
- if (flag_pic && TARGET_PORTABLE_RUNTIME)
- {
- warning ("PIC code generation is not supported in the portable runtime model\n");
- }
-
- if (flag_pic && (TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS))
- {
- warning ("PIC code generation is not compatible with fast indirect calls\n");
- }
-
- if (flag_pic && profile_flag)
- {
- warning ("PIC code generation is not compatible with profiling\n");
- }
-
- if (TARGET_SPACE && (flag_pic || profile_flag))
- {
- warning ("Out of line entry/exit sequences are not compatible\n");
- warning ("with PIC or profiling\n");
- }
-
- if (! TARGET_GAS && write_symbols != NO_DEBUG)
- {
- warning ("-g is only supported when using GAS on this processor,");
- warning ("-g option disabled.");
- write_symbols = NO_DEBUG;
- }
-}
-
-
-/* Return non-zero only if OP is a register of mode MODE,
- or CONST0_RTX. */
-int
-reg_or_0_operand (op, mode)
- rtx op;
- enum machine_mode mode;
-{
- return (op == CONST0_RTX (mode) || register_operand (op, mode));
-}
-
-/* Return non-zero if OP is suitable for use in a call to a named
- function.
-
- (???) For 2.5 try to eliminate either call_operand_address or
- function_label_operand, they perform very similar functions. */
-int
-call_operand_address (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
-{
- return (CONSTANT_P (op) && ! TARGET_PORTABLE_RUNTIME);
-}
-
-/* Return 1 if X contains a symbolic expression. We know these
- expressions will have one of a few well defined forms, so
- we need only check those forms. */
-int
-symbolic_expression_p (x)
- register rtx x;
-{
-
- /* Strip off any HIGH. */
- if (GET_CODE (x) == HIGH)
- x = XEXP (x, 0);
-
- return (symbolic_operand (x, VOIDmode));
-}
-
-int
-symbolic_operand (op, mode)
- register rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
-{
- switch (GET_CODE (op))
- {
- case SYMBOL_REF:
- case LABEL_REF:
- return 1;
- case CONST:
- op = XEXP (op, 0);
- return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
- || GET_CODE (XEXP (op, 0)) == LABEL_REF)
- && GET_CODE (XEXP (op, 1)) == CONST_INT);
- default:
- return 0;
- }
-}
-
-/* Return truth value of statement that OP is a symbolic memory
- operand of mode MODE. */
-
-int
-symbolic_memory_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
-{
- if (GET_CODE (op) == SUBREG)
- op = SUBREG_REG (op);
- if (GET_CODE (op) != MEM)
- return 0;
- op = XEXP (op, 0);
- return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST
- || GET_CODE (op) == HIGH || GET_CODE (op) == LABEL_REF);
-}
-
-/* Return 1 if the operand is either a register or a memory operand that is
- not symbolic. */
-
-int
-reg_or_nonsymb_mem_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
-{
- if (register_operand (op, mode))
- return 1;
-
- if (memory_operand (op, mode) && ! symbolic_memory_operand (op, mode))
- return 1;
-
- return 0;
-}
-
-/* Return 1 if the operand is either a register, zero, or a memory operand
- that is not symbolic. */
-
-int
-reg_or_0_or_nonsymb_mem_operand (op, mode)
- register rtx op;
- enum machine_mode mode;
-{
- if (register_operand (op, mode))
- return 1;
-
- if (op == CONST0_RTX (mode))
- return 1;
-
- if (memory_operand (op, mode) && ! symbolic_memory_operand (op, mode))
- return 1;
-
- return 0;
-}
-
-/* Accept any constant that can be moved in one instructions into a
- general register. */
-int
-cint_ok_for_move (intval)
- HOST_WIDE_INT intval;
-{
- /* OK if ldo, ldil, or zdepi, can be used. */
- return (VAL_14_BITS_P (intval) || (intval & 0x7ff) == 0
- || zdepi_cint_p (intval));
-}
-
-/* Accept anything that can be moved in one instruction into a general
- register. */
-int
-move_operand (op, mode)
- rtx op;
- enum machine_mode mode;
-{
- if (register_operand (op, mode))
- return 1;
-
- if (GET_CODE (op) == CONSTANT_P_RTX)
- return 1;
-
- if (GET_CODE (op) == CONST_INT)
- return cint_ok_for_move (INTVAL (op));
-
- if (GET_CODE (op) == SUBREG)
- op = SUBREG_REG (op);
- if (GET_CODE (op) != MEM)
- return 0;
-
- op = XEXP (op, 0);
- if (GET_CODE (op) == LO_SUM)
- return (register_operand (XEXP (op, 0), Pmode)
- && CONSTANT_P (XEXP (op, 1)));
-
- /* Since move_operand is only used for source operands, we can always
- allow scaled indexing! */
- if (! TARGET_DISABLE_INDEXING
- && GET_CODE (op) == PLUS
- && ((GET_CODE (XEXP (op, 0)) == MULT
- && GET_CODE (XEXP (XEXP (op, 0), 0)) == REG
- && GET_CODE (XEXP (XEXP (op, 0), 1)) == CONST_INT
- && INTVAL (XEXP (XEXP (op, 0), 1)) == GET_MODE_SIZE (mode)
- && GET_CODE (XEXP (op, 1)) == REG)
- || (GET_CODE (XEXP (op, 1)) == MULT
- &&GET_CODE (XEXP (XEXP (op, 1), 0)) == REG
- && GET_CODE (XEXP (XEXP (op, 1), 1)) == CONST_INT
- && INTVAL (XEXP (XEXP (op, 1), 1)) == GET_MODE_SIZE (mode)
- && GET_CODE (XEXP (op, 0)) == REG)))
- return 1;
-
- return memory_address_p (mode, op);
-}
-
-/* Accept REG and any CONST_INT that can be moved in one instruction into a
- general register. */
-int
-reg_or_cint_move_operand (op, mode)
- rtx op;
- enum machine_mode mode;
-{
- if (register_operand (op, mode))
- return 1;
-
- if (GET_CODE (op) == CONST_INT)
- return cint_ok_for_move (INTVAL (op));
-
- return 0;
-}
-
-int
-pic_label_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
-{
- if (!flag_pic)
- return 0;
-
- switch (GET_CODE (op))
- {
- case LABEL_REF:
- return 1;
- case CONST:
- op = XEXP (op, 0);
- return (GET_CODE (XEXP (op, 0)) == LABEL_REF
- && GET_CODE (XEXP (op, 1)) == CONST_INT);
- default:
- return 0;
- }
-}
-
-int
-fp_reg_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
-{
- return reg_renumber && FP_REG_P (op);
-}
-
-
-
-/* Return truth value of whether OP can be used as an operand in a
- three operand arithmetic insn that accepts registers of mode MODE
- or 14-bit signed integers. */
-int
-arith_operand (op, mode)
- rtx op;
- enum machine_mode mode;
-{
- return (register_operand (op, mode)
- || (GET_CODE (op) == CONST_INT && INT_14_BITS (op)));
-}
-
-/* Return truth value of whether OP can be used as an operand in a
- three operand arithmetic insn that accepts registers of mode MODE
- or 11-bit signed integers. */
-int
-arith11_operand (op, mode)
- rtx op;
- enum machine_mode mode;
-{
- return (register_operand (op, mode)
- || (GET_CODE (op) == CONST_INT && INT_11_BITS (op)));
-}
-
-/* A constant integer suitable for use in a PRE_MODIFY memory
- reference. */
-int
-pre_cint_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
-{
- return (GET_CODE (op) == CONST_INT
- && INTVAL (op) >= -0x2000 && INTVAL (op) < 0x10);
-}
-
-/* A constant integer suitable for use in a POST_MODIFY memory
- reference. */
-int
-post_cint_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
-{
- return (GET_CODE (op) == CONST_INT
- && INTVAL (op) < 0x2000 && INTVAL (op) >= -0x10);
-}
-
-int
-arith_double_operand (op, mode)
- rtx op;
- enum machine_mode mode;
-{
- return (register_operand (op, mode)
- || (GET_CODE (op) == CONST_DOUBLE
- && GET_MODE (op) == mode
- && VAL_14_BITS_P (CONST_DOUBLE_LOW (op))
- && ((CONST_DOUBLE_HIGH (op) >= 0)
- == ((CONST_DOUBLE_LOW (op) & 0x1000) == 0))));
-}
-
-/* Return truth value of whether OP is a integer which fits the
- range constraining immediate operands in three-address insns, or
- is an integer register. */
-
-int
-ireg_or_int5_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
-{
- return ((GET_CODE (op) == CONST_INT && INT_5_BITS (op))
- || (GET_CODE (op) == REG && REGNO (op) > 0 && REGNO (op) < 32));
-}
-
-/* Return truth value of whether OP is a integer which fits the
- range constraining immediate operands in three-address insns. */
-
-int
-int5_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
-{
- return (GET_CODE (op) == CONST_INT && INT_5_BITS (op));
-}
-
-int
-uint5_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
-{
- return (GET_CODE (op) == CONST_INT && INT_U5_BITS (op));
-}
-
-int
-int11_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
-{
- return (GET_CODE (op) == CONST_INT && INT_11_BITS (op));
-}
-
-int
-uint32_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
-{
-#if HOST_BITS_PER_WIDE_INT > 32
- /* All allowed constants will fit a CONST_INT. */
- return (GET_CODE (op) == CONST_INT
- && (INTVAL (op) >= 0 && INTVAL (op) < 0x100000000L));
-#else
- return (GET_CODE (op) == CONST_INT
- || (GET_CODE (op) == CONST_DOUBLE
- && CONST_DOUBLE_HIGH (op) == 0));
-#endif
-}
-
-int
-arith5_operand (op, mode)
- rtx op;
- enum machine_mode mode;
-{
- return register_operand (op, mode) || int5_operand (op, mode);
-}
-
-/* True iff zdepi can be used to generate this CONST_INT. */
-int
-zdepi_cint_p (x)
- unsigned HOST_WIDE_INT x;
-{
- unsigned HOST_WIDE_INT lsb_mask, t;
-
- /* This might not be obvious, but it's at least fast.
- This function is critical; we don't have the time loops would take. */
- lsb_mask = x & -x;
- t = ((x >> 4) + lsb_mask) & ~(lsb_mask - 1);
- /* Return true iff t is a power of two. */
- return ((t & (t - 1)) == 0);
-}
-
-/* True iff depi or extru can be used to compute (reg & mask).
- Accept bit pattern like these:
- 0....01....1
- 1....10....0
- 1..10..01..1 */
-int
-and_mask_p (mask)
- unsigned HOST_WIDE_INT mask;
-{
- mask = ~mask;
- mask += mask & -mask;
- return (mask & (mask - 1)) == 0;
-}
-
-/* True iff depi or extru can be used to compute (reg & OP). */
-int
-and_operand (op, mode)
- rtx op;
- enum machine_mode mode;
-{
- return (register_operand (op, mode)
- || (GET_CODE (op) == CONST_INT && and_mask_p (INTVAL (op))));
-}
-
-/* True iff depi can be used to compute (reg | MASK). */
-int
-ior_mask_p (mask)
- unsigned HOST_WIDE_INT mask;
-{
- mask += mask & -mask;
- return (mask & (mask - 1)) == 0;
-}
-
-/* True iff depi can be used to compute (reg | OP). */
-int
-ior_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
-{
- return (GET_CODE (op) == CONST_INT && ior_mask_p (INTVAL (op)));
-}
-
-int
-lhs_lshift_operand (op, mode)
- rtx op;
- enum machine_mode mode;
-{
- return register_operand (op, mode) || lhs_lshift_cint_operand (op, mode);
-}
-
-/* True iff OP is a CONST_INT of the forms 0...0xxxx or 0...01...1xxxx.
- Such values can be the left hand side x in (x << r), using the zvdepi
- instruction. */
-int
-lhs_lshift_cint_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
-{
- unsigned HOST_WIDE_INT x;
- if (GET_CODE (op) != CONST_INT)
- return 0;
- x = INTVAL (op) >> 4;
- return (x & (x + 1)) == 0;
-}
-
-int
-arith32_operand (op, mode)
- rtx op;
- enum machine_mode mode;
-{
- return register_operand (op, mode) || GET_CODE (op) == CONST_INT;
-}
-
-int
-pc_or_label_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
-{
- return (GET_CODE (op) == PC || GET_CODE (op) == LABEL_REF);
-}
-
-/* Legitimize PIC addresses. If the address is already
- position-independent, we return ORIG. Newly generated
- position-independent addresses go to REG. If we need more
- than one register, we lose. */
-
-rtx
-legitimize_pic_address (orig, mode, reg)
- rtx orig, reg;
- enum machine_mode mode ATTRIBUTE_UNUSED;
-{
- rtx pic_ref = orig;
-
- /* Labels need special handling. */
- if (pic_label_operand (orig))
- {
- emit_insn (gen_pic_load_label (reg, orig));
- current_function_uses_pic_offset_table = 1;
- return reg;
- }
- if (GET_CODE (orig) == SYMBOL_REF)
- {
- if (reg == 0)
- abort ();
-
- if (flag_pic == 2)
- {
- emit_insn (gen_pic2_highpart (reg, pic_offset_table_rtx, orig));
- pic_ref
- = gen_rtx_MEM (Pmode,
- gen_rtx_LO_SUM (Pmode, reg,
- gen_rtx_UNSPEC (SImode,
- gen_rtvec (1, orig),
- 0)));
- }
- else
- pic_ref = gen_rtx_MEM (Pmode,
- gen_rtx_PLUS (Pmode,
- pic_offset_table_rtx, orig));
- current_function_uses_pic_offset_table = 1;
- RTX_UNCHANGING_P (pic_ref) = 1;
- emit_move_insn (reg, pic_ref);
- return reg;
- }
- else if (GET_CODE (orig) == CONST)
- {
- rtx base;
-
- if (GET_CODE (XEXP (orig, 0)) == PLUS
- && XEXP (XEXP (orig, 0), 0) == pic_offset_table_rtx)
- return orig;
-
- if (reg == 0)
- abort ();
-
- if (GET_CODE (XEXP (orig, 0)) == PLUS)
- {
- base = legitimize_pic_address (XEXP (XEXP (orig, 0), 0), Pmode, reg);
- orig = legitimize_pic_address (XEXP (XEXP (orig, 0), 1), Pmode,
- base == reg ? 0 : reg);
- }
- else abort ();
- if (GET_CODE (orig) == CONST_INT)
- {
- if (INT_14_BITS (orig))
- return plus_constant_for_output (base, INTVAL (orig));
- orig = force_reg (Pmode, orig);
- }
- pic_ref = gen_rtx_PLUS (Pmode, base, orig);
- /* Likewise, should we set special REG_NOTEs here? */
- }
- return pic_ref;
-}
-
-/* Try machine-dependent ways of modifying an illegitimate address
- to be legitimate. If we find one, return the new, valid address.
- This macro is used in only one place: `memory_address' in explow.c.
-
- OLDX is the address as it was before break_out_memory_refs was called.
- In some cases it is useful to look at this to decide what needs to be done.
-
- MODE and WIN are passed so that this macro can use
- GO_IF_LEGITIMATE_ADDRESS.
-
- It is always safe for this macro to do nothing. It exists to recognize
- opportunities to optimize the output.
-
- For the PA, transform:
-
- memory(X + <large int>)
-
- into:
-
- if (<large int> & mask) >= 16
- Y = (<large int> & ~mask) + mask + 1 Round up.
- else
- Y = (<large int> & ~mask) Round down.
- Z = X + Y
- memory (Z + (<large int> - Y));
-
- This is for CSE to find several similar references, and only use one Z.
-
- X can either be a SYMBOL_REF or REG, but because combine can not
- perform a 4->2 combination we do nothing for SYMBOL_REF + D where
- D will not fit in 14 bits.
-
- MODE_FLOAT references allow displacements which fit in 5 bits, so use
- 0x1f as the mask.
-
- MODE_INT references allow displacements which fit in 14 bits, so use
- 0x3fff as the mask.
-
- This relies on the fact that most mode MODE_FLOAT references will use FP
- registers and most mode MODE_INT references will use integer registers.
- (In the rare case of an FP register used in an integer MODE, we depend
- on secondary reloads to clean things up.)
-
-
- It is also beneficial to handle (plus (mult (X) (Y)) (Z)) in a special
- manner if Y is 2, 4, or 8. (allows more shadd insns and shifted indexed
- addressing modes to be used).
-
- Put X and Z into registers. Then put the entire expression into
- a register. */
-
-rtx
-hppa_legitimize_address (x, oldx, mode)
- rtx x, oldx ATTRIBUTE_UNUSED;
- enum machine_mode mode;
-{
- rtx orig = x;
-
- if (flag_pic)
- return legitimize_pic_address (x, mode, gen_reg_rtx (Pmode));
-
- /* Strip off CONST. */
- if (GET_CODE (x) == CONST)
- x = XEXP (x, 0);
-
- /* Special case. Get the SYMBOL_REF into a register and use indexing.
- That should always be safe. */
- if (GET_CODE (x) == PLUS
- && GET_CODE (XEXP (x, 0)) == REG
- && GET_CODE (XEXP (x, 1)) == SYMBOL_REF)
- {
- rtx reg = force_reg (SImode, XEXP (x, 1));
- return force_reg (SImode, gen_rtx_PLUS (SImode, reg, XEXP (x, 0)));
- }
-
- /* Note we must reject symbols which represent function addresses
- since the assembler/linker can't handle arithmetic on plabels. */
- if (GET_CODE (x) == PLUS
- && GET_CODE (XEXP (x, 1)) == CONST_INT
- && ((GET_CODE (XEXP (x, 0)) == SYMBOL_REF
- && !FUNCTION_NAME_P (XSTR (XEXP (x, 0), 0)))
- || GET_CODE (XEXP (x, 0)) == REG))
- {
- rtx int_part, ptr_reg;
- int newoffset;
- int offset = INTVAL (XEXP (x, 1));
- int mask = GET_MODE_CLASS (mode) == MODE_FLOAT ? 0x1f : 0x3fff;
-
- /* CYGNUS LOCAL pa8000/law */
- mask = (GET_MODE_CLASS (mode) == MODE_FLOAT
- ? (TARGET_PARISC_2_0 ? 0x3fff : 0x1f) : 0x3fff);
- /* END CYGNUS LOCAL */
-
- /* Choose which way to round the offset. Round up if we
- are >= halfway to the next boundary. */
- if ((offset & mask) >= ((mask + 1) / 2))
- newoffset = (offset & ~ mask) + mask + 1;
- else
- newoffset = (offset & ~ mask);
-
- /* If the newoffset will not fit in 14 bits (ldo), then
- handling this would take 4 or 5 instructions (2 to load
- the SYMBOL_REF + 1 or 2 to load the newoffset + 1 to
- add the new offset and the SYMBOL_REF.) Combine can
- not handle 4->2 or 5->2 combinations, so do not create
- them. */
- if (! VAL_14_BITS_P (newoffset)
- && GET_CODE (XEXP (x, 0)) == SYMBOL_REF)
- {
- rtx const_part
- = gen_rtx_CONST (VOIDmode, gen_rtx_PLUS (Pmode,
- XEXP (x, 0),
- GEN_INT (newoffset)));
- rtx tmp_reg
- = force_reg (Pmode,
- gen_rtx_HIGH (Pmode, const_part));
- ptr_reg
- = force_reg (Pmode,
- gen_rtx_LO_SUM (Pmode, tmp_reg, const_part));
- }
- else
- {
- if (! VAL_14_BITS_P (newoffset))
- int_part = force_reg (Pmode, GEN_INT (newoffset));
- else
- int_part = GEN_INT (newoffset);
-
- ptr_reg = force_reg (Pmode,
- gen_rtx_PLUS (Pmode,
- force_reg (Pmode, XEXP (x, 0)),
- int_part));
- }
- return plus_constant (ptr_reg, offset - newoffset);
- }
-
- /* Handle (plus (mult (a) (shadd_constant)) (b)). */
-
- if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == MULT
- && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
- && shadd_constant_p (INTVAL (XEXP (XEXP (x, 0), 1)))
- && (GET_RTX_CLASS (GET_CODE (XEXP (x, 1))) == 'o'
- || GET_CODE (XEXP (x, 1)) == SUBREG)
- && GET_CODE (XEXP (x, 1)) != CONST)
- {
- int val = INTVAL (XEXP (XEXP (x, 0), 1));
- rtx reg1, reg2;
-
- reg1 = XEXP (x, 1);
- if (GET_CODE (reg1) != REG)
- reg1 = force_reg (Pmode, force_operand (reg1, 0));
-
- reg2 = XEXP (XEXP (x, 0), 0);
- if (GET_CODE (reg2) != REG)
- reg2 = force_reg (Pmode, force_operand (reg2, 0));
-
- return force_reg (Pmode, gen_rtx_PLUS (Pmode,
- gen_rtx_MULT (Pmode, reg2,
- GEN_INT (val)),
- reg1));
- }
-
- /* Similarly for (plus (plus (mult (a) (shadd_constant)) (b)) (c)).
-
- Only do so for floating point modes since this is more speculative
- and we lose if it's an integer store. */
- if (GET_CODE (x) == PLUS
- && GET_CODE (XEXP (x, 0)) == PLUS
- && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
- && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == CONST_INT
- && shadd_constant_p (INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1)))
- && (mode == SFmode || mode == DFmode))
- {
-
- /* First, try and figure out what to use as a base register. */
- rtx reg1, reg2, base, idx, orig_base;
-
- reg1 = XEXP (XEXP (x, 0), 1);
- reg2 = XEXP (x, 1);
- base = NULL_RTX;
- idx = NULL_RTX;
-
- /* Make sure they're both regs. If one was a SYMBOL_REF [+ const],
- then emit_move_sequence will turn on REGNO_POINTER_FLAG so we'll
- know it's a base register below. */
- if (GET_CODE (reg1) != REG)
- reg1 = force_reg (Pmode, force_operand (reg1, 0));
-
- if (GET_CODE (reg2) != REG)
- reg2 = force_reg (Pmode, force_operand (reg2, 0));
-
- /* Figure out what the base and index are. */
-
- if (GET_CODE (reg1) == REG
- && REGNO_POINTER_FLAG (REGNO (reg1)))
- {
- base = reg1;
- orig_base = XEXP (XEXP (x, 0), 1);
- idx = gen_rtx_PLUS (Pmode,
- gen_rtx_MULT (Pmode,
- XEXP (XEXP (XEXP (x, 0), 0), 0),
- XEXP (XEXP (XEXP (x, 0), 0), 1)),
- XEXP (x, 1));
- }
- else if (GET_CODE (reg2) == REG
- && REGNO_POINTER_FLAG (REGNO (reg2)))
- {
- base = reg2;
- orig_base = XEXP (x, 1);
- idx = XEXP (x, 0);
- }
-
- if (base == 0)
- return orig;
-
- /* If the index adds a large constant, try to scale the
- constant so that it can be loaded with only one insn. */
- if (GET_CODE (XEXP (idx, 1)) == CONST_INT
- && VAL_14_BITS_P (INTVAL (XEXP (idx, 1))
- / INTVAL (XEXP (XEXP (idx, 0), 1)))
- && INTVAL (XEXP (idx, 1)) % INTVAL (XEXP (XEXP (idx, 0), 1)) == 0)
- {
- /* Divide the CONST_INT by the scale factor, then add it to A. */
- int val = INTVAL (XEXP (idx, 1));
-
- val /= INTVAL (XEXP (XEXP (idx, 0), 1));
- reg1 = XEXP (XEXP (idx, 0), 0);
- if (GET_CODE (reg1) != REG)
- reg1 = force_reg (Pmode, force_operand (reg1, 0));
-
- reg1 = force_reg (Pmode, gen_rtx_PLUS (Pmode, reg1, GEN_INT (val)));
-
- /* We can now generate a simple scaled indexed address. */
- return force_reg (Pmode,
- gen_rtx_PLUS (Pmode,
- gen_rtx_MULT (Pmode, reg1,
- XEXP (XEXP (idx, 0), 1)),
- base));
- }
-
- /* If B + C is still a valid base register, then add them. */
- if (GET_CODE (XEXP (idx, 1)) == CONST_INT
- && INTVAL (XEXP (idx, 1)) <= 4096
- && INTVAL (XEXP (idx, 1)) >= -4096)
- {
- int val = INTVAL (XEXP (XEXP (idx, 0), 1));
- rtx reg1, reg2;
-
- reg1 = force_reg (Pmode, gen_rtx_PLUS (Pmode, base, XEXP (idx, 1)));
-
- reg2 = XEXP (XEXP (idx, 0), 0);
- if (GET_CODE (reg2) != CONST_INT)
- reg2 = force_reg (Pmode, force_operand (reg2, 0));
-
- return force_reg (Pmode, gen_rtx_PLUS (Pmode,
- gen_rtx_MULT (Pmode, reg2,
- GEN_INT (val)),
- reg1));
- }
-
- /* Get the index into a register, then add the base + index and
- return a register holding the result. */
-
- /* First get A into a register. */
- reg1 = XEXP (XEXP (idx, 0), 0);
- if (GET_CODE (reg1) != REG)
- reg1 = force_reg (Pmode, force_operand (reg1, 0));
-
- /* And get B into a register. */
- reg2 = XEXP (idx, 1);
- if (GET_CODE (reg2) != REG)
- reg2 = force_reg (Pmode, force_operand (reg2, 0));
-
- reg1 = force_reg (Pmode,
- gen_rtx_PLUS (Pmode,
- gen_rtx_MULT (Pmode, reg1,
- XEXP (XEXP (idx, 0), 1)),
- reg2));
-
- /* Add the result to our base register and return. */
- return force_reg (Pmode, gen_rtx_PLUS (Pmode, base, reg1));
-
- }
-
- /* Uh-oh. We might have an address for x[n-100000]. This needs
- special handling to avoid creating an indexed memory address
- with x-100000 as the base.
-
- If the constant part is small enough, then it's still safe because
- there is a guard page at the beginning and end of the data segment.
-
- Scaled references are common enough that we want to try and rearrange the
- terms so that we can use indexing for these addresses too. Only
- do the optimization for floatint point modes. */
-
- if (GET_CODE (x) == PLUS
- && symbolic_expression_p (XEXP (x, 1)))
- {
- /* Ugly. We modify things here so that the address offset specified
- by the index expression is computed first, then added to x to form
- the entire address. */
-
- rtx regx1, regx2, regy1, regy2, y;
-
- /* Strip off any CONST. */
- y = XEXP (x, 1);
- if (GET_CODE (y) == CONST)
- y = XEXP (y, 0);
-
- if (GET_CODE (y) == PLUS || GET_CODE (y) == MINUS)
- {
- /* See if this looks like
- (plus (mult (reg) (shadd_const))
- (const (plus (symbol_ref) (const_int))))
-
- Where const_int is small. In that case the const
- expression is a valid pointer for indexing.
-
- If const_int is big, but can be divided evenly by shadd_const
- and added to (reg). This allows more scaled indexed addresses. */
- if (GET_CODE (XEXP (y, 0)) == SYMBOL_REF
- && GET_CODE (XEXP (x, 0)) == MULT
- && GET_CODE (XEXP (y, 1)) == CONST_INT
- && INTVAL (XEXP (y, 1)) >= -4096
- && INTVAL (XEXP (y, 1)) <= 4095
- && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
- && shadd_constant_p (INTVAL (XEXP (XEXP (x, 0), 1))))
- {
- int val = INTVAL (XEXP (XEXP (x, 0), 1));
- rtx reg1, reg2;
-
- reg1 = XEXP (x, 1);
- if (GET_CODE (reg1) != REG)
- reg1 = force_reg (Pmode, force_operand (reg1, 0));
-
- reg2 = XEXP (XEXP (x, 0), 0);
- if (GET_CODE (reg2) != REG)
- reg2 = force_reg (Pmode, force_operand (reg2, 0));
-
- return force_reg (Pmode,
- gen_rtx_PLUS (Pmode,
- gen_rtx_MULT (Pmode, reg2,
- GEN_INT (val)),
- reg1));
- }
- else if ((mode == DFmode || mode == SFmode)
- && GET_CODE (XEXP (y, 0)) == SYMBOL_REF
- && GET_CODE (XEXP (x, 0)) == MULT
- && GET_CODE (XEXP (y, 1)) == CONST_INT
- && INTVAL (XEXP (y, 1)) % INTVAL (XEXP (XEXP (x, 0), 1)) == 0
- && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
- && shadd_constant_p (INTVAL (XEXP (XEXP (x, 0), 1))))
- {
- regx1
- = force_reg (Pmode, GEN_INT (INTVAL (XEXP (y, 1))
- / INTVAL (XEXP (XEXP (x, 0), 1))));
- regx2 = XEXP (XEXP (x, 0), 0);
- if (GET_CODE (regx2) != REG)
- regx2 = force_reg (Pmode, force_operand (regx2, 0));
- regx2 = force_reg (Pmode, gen_rtx_fmt_ee (GET_CODE (y), Pmode,
- regx2, regx1));
- return force_reg (Pmode,
- gen_rtx_PLUS (Pmode,
- gen_rtx_MULT (Pmode, regx2,
- XEXP (XEXP (x, 0),
- 1)),
- force_reg (Pmode, XEXP (y, 0))));
- }
- else if (GET_CODE (XEXP (y, 1)) == CONST_INT
- && INTVAL (XEXP (y, 1)) >= -4096
- && INTVAL (XEXP (y, 1)) <= 4095)
- {
- /* This is safe because of the guard page at the
- beginning and end of the data space. Just
- return the original address. */
- return orig;
- }
- else
- {
- /* Doesn't look like one we can optimize. */
- regx1 = force_reg (Pmode, force_operand (XEXP (x, 0), 0));
- regy1 = force_reg (Pmode, force_operand (XEXP (y, 0), 0));
- regy2 = force_reg (Pmode, force_operand (XEXP (y, 1), 0));
- regx1 = force_reg (Pmode,
- gen_rtx_fmt_ee (GET_CODE (y), Pmode,
- regx1, regy2));
- return force_reg (Pmode, gen_rtx_PLUS (Pmode, regx1, regy1));
- }
- }
- }
-
- return orig;
-}
-
-/* For the HPPA, REG and REG+CONST is cost 0
- and addresses involving symbolic constants are cost 2.
-
- PIC addresses are very expensive.
-
- It is no coincidence that this has the same structure
- as GO_IF_LEGITIMATE_ADDRESS. */
-int
-hppa_address_cost (X)
- rtx X;
-{
- if (GET_CODE (X) == PLUS)
- return 1;
- else if (GET_CODE (X) == LO_SUM)
- return 1;
- else if (GET_CODE (X) == HIGH)
- return 2;
- return 4;
-}
-
-/* Emit insns to move operands[1] into operands[0].
-
- Return 1 if we have written out everything that needs to be done to
- do the move. Otherwise, return 0 and the caller will emit the move
- normally. */
-
-int
-emit_move_sequence (operands, mode, scratch_reg)
- rtx *operands;
- enum machine_mode mode;
- rtx scratch_reg;
-{
- register rtx operand0 = operands[0];
- register rtx operand1 = operands[1];
- register rtx tem;
-
- if (scratch_reg
- && reload_in_progress && GET_CODE (operand0) == REG
- && REGNO (operand0) >= FIRST_PSEUDO_REGISTER)
- operand0 = reg_equiv_mem[REGNO (operand0)];
- else if (scratch_reg
- && reload_in_progress && GET_CODE (operand0) == SUBREG
- && GET_CODE (SUBREG_REG (operand0)) == REG
- && REGNO (SUBREG_REG (operand0)) >= FIRST_PSEUDO_REGISTER)
- {
- SUBREG_REG (operand0) = reg_equiv_mem[REGNO (SUBREG_REG (operand0))];
- operand0 = alter_subreg (operand0);
- }
-
- if (scratch_reg
- && reload_in_progress && GET_CODE (operand1) == REG
- && REGNO (operand1) >= FIRST_PSEUDO_REGISTER)
- operand1 = reg_equiv_mem[REGNO (operand1)];
- else if (scratch_reg
- && reload_in_progress && GET_CODE (operand1) == SUBREG
- && GET_CODE (SUBREG_REG (operand1)) == REG
- && REGNO (SUBREG_REG (operand1)) >= FIRST_PSEUDO_REGISTER)
- {
- SUBREG_REG (operand1) = reg_equiv_mem[REGNO (SUBREG_REG (operand1))];
- operand1 = alter_subreg (operand1);
- }
-
- if (scratch_reg && reload_in_progress && GET_CODE (operand0) == MEM
- && ((tem = find_replacement (&XEXP (operand0, 0)))
- != XEXP (operand0, 0)))
- operand0 = gen_rtx_MEM (GET_MODE (operand0), tem);
- if (scratch_reg && reload_in_progress && GET_CODE (operand1) == MEM
- && ((tem = find_replacement (&XEXP (operand1, 0)))
- != XEXP (operand1, 0)))
- operand1 = gen_rtx_MEM (GET_MODE (operand1), tem);
-
- /* Handle secondary reloads for loads/stores of FP registers from
- REG+D addresses where D does not fit in 5 bits, including
- (subreg (mem (addr))) cases. */
- if (fp_reg_operand (operand0, mode)
- && ((GET_CODE (operand1) == MEM
- && ! memory_address_p (DFmode, XEXP (operand1, 0)))
- || ((GET_CODE (operand1) == SUBREG
- && GET_CODE (XEXP (operand1, 0)) == MEM
- && !memory_address_p (DFmode, XEXP (XEXP (operand1, 0), 0)))))
- && scratch_reg)
- {
- if (GET_CODE (operand1) == SUBREG)
- operand1 = XEXP (operand1, 0);
-
- scratch_reg = gen_rtx_REG (SImode, REGNO (scratch_reg));
-
- /* D might not fit in 14 bits either; for such cases load D into
- scratch reg. */
- if (!memory_address_p (SImode, XEXP (operand1, 0)))
- {
- emit_move_insn (scratch_reg, XEXP (XEXP (operand1, 0), 1));
- emit_move_insn (scratch_reg, gen_rtx_fmt_ee (GET_CODE (XEXP (operand1, 0)),
- SImode,
- XEXP (XEXP (operand1, 0), 0),
- scratch_reg));
- }
- else
- emit_move_insn (scratch_reg, XEXP (operand1, 0));
- emit_insn (gen_rtx_SET (VOIDmode, operand0, gen_rtx_MEM (mode,
- scratch_reg)));
- return 1;
- }
- else if (fp_reg_operand (operand1, mode)
- && ((GET_CODE (operand0) == MEM
- && ! memory_address_p (DFmode, XEXP (operand0, 0)))
- || ((GET_CODE (operand0) == SUBREG)
- && GET_CODE (XEXP (operand0, 0)) == MEM
- && !memory_address_p (DFmode, XEXP (XEXP (operand0, 0), 0))))
- && scratch_reg)
- {
- if (GET_CODE (operand0) == SUBREG)
- operand0 = XEXP (operand0, 0);
-
- scratch_reg = gen_rtx_REG (SImode, REGNO (scratch_reg));
- /* D might not fit in 14 bits either; for such cases load D into
- scratch reg. */
- if (!memory_address_p (SImode, XEXP (operand0, 0)))
- {
- emit_move_insn (scratch_reg, XEXP (XEXP (operand0, 0), 1));
- emit_move_insn (scratch_reg, gen_rtx_fmt_ee (GET_CODE (XEXP (operand0,
- 0)),
- SImode,
- XEXP (XEXP (operand0, 0),
- 0),
- scratch_reg));
- }
- else
- emit_move_insn (scratch_reg, XEXP (operand0, 0));
- emit_insn (gen_rtx_SET (VOIDmode, gen_rtx_MEM (mode, scratch_reg),
- operand1));
- return 1;
- }
- /* Handle secondary reloads for loads of FP registers from constant
- expressions by forcing the constant into memory.
-
- use scratch_reg to hold the address of the memory location.
-
- ??? The proper fix is to change PREFERRED_RELOAD_CLASS to return
- NO_REGS when presented with a const_int and an register class
- containing only FP registers. Doing so unfortunately creates
- more problems than it solves. Fix this for 2.5. */
- else if (fp_reg_operand (operand0, mode)
- && CONSTANT_P (operand1)
- && scratch_reg)
- {
- rtx xoperands[2];
-
- /* Force the constant into memory and put the address of the
- memory location into scratch_reg. */
- xoperands[0] = scratch_reg;
- xoperands[1] = XEXP (force_const_mem (mode, operand1), 0);
- emit_move_sequence (xoperands, Pmode, 0);
-
- /* Now load the destination register. */
- emit_insn (gen_rtx_SET (mode, operand0, gen_rtx_MEM (mode, scratch_reg)));
- return 1;
- }
- /* Handle secondary reloads for SAR. These occur when trying to load
- the SAR from memory a FP register, or with a constant. */
- else if (GET_CODE (operand0) == REG
- && REGNO_REG_CLASS (REGNO (operand0)) == SHIFT_REGS
- && (GET_CODE (operand1) == MEM
- || GET_CODE (operand1) == CONST_INT
- || (GET_CODE (operand1) == REG
- && FP_REG_CLASS_P (REGNO_REG_CLASS (REGNO (operand1)))))
- && scratch_reg)
- {
- /* D might not fit in 14 bits either; for such cases load D into
- scratch reg. */
- if (GET_CODE (operand1) == MEM
- && !memory_address_p (SImode, XEXP (operand1, 0)))
- {
- emit_move_insn (scratch_reg, XEXP (XEXP (operand1, 0), 1));
- emit_move_insn (scratch_reg, gen_rtx_fmt_ee (GET_CODE (XEXP (operand1,
- 0)),
- SImode,
- XEXP (XEXP (operand1, 0),
- 0),
- scratch_reg));
- emit_move_insn (scratch_reg, gen_rtx_MEM (GET_MODE (operand1),
- scratch_reg));
- }
- else
- emit_move_insn (scratch_reg, operand1);
- emit_move_insn (operand0, scratch_reg);
- return 1;
- }
- /* Handle most common case: storing into a register. */
- else if (register_operand (operand0, mode))
- {
- if (register_operand (operand1, mode)
- || (GET_CODE (operand1) == CONST_INT && INT_14_BITS (operand1))
- || (operand1 == CONST0_RTX (mode))
- || (GET_CODE (operand1) == HIGH
- && !symbolic_operand (XEXP (operand1, 0), VOIDmode))
- /* Only `general_operands' can come here, so MEM is ok. */
- || GET_CODE (operand1) == MEM)
- {
- /* Run this case quickly. */
- emit_insn (gen_rtx_SET (VOIDmode, operand0, operand1));
- return 1;
- }
- }
- else if (GET_CODE (operand0) == MEM)
- {
- if (mode == DFmode && operand1 == CONST0_RTX (mode)
- && !(reload_in_progress || reload_completed))
- {
- rtx temp = gen_reg_rtx (DFmode);
-
- emit_insn (gen_rtx_SET (VOIDmode, temp, operand1));
- emit_insn (gen_rtx_SET (VOIDmode, operand0, temp));
- return 1;
- }
- if (register_operand (operand1, mode) || operand1 == CONST0_RTX (mode))
- {
- /* Run this case quickly. */
- emit_insn (gen_rtx_SET (VOIDmode, operand0, operand1));
- return 1;
- }
- if (! (reload_in_progress || reload_completed))
- {
- operands[0] = validize_mem (operand0);
- operands[1] = operand1 = force_reg (mode, operand1);
- }
- }
-
- /* Simplify the source if we need to.
- Note we do have to handle function labels here, even though we do
- not consider them legitimate constants. Loop optimizations can
- call the emit_move_xxx with one as a source. */
- if ((GET_CODE (operand1) != HIGH && immediate_operand (operand1, mode))
- || function_label_operand (operand1, mode)
- || (GET_CODE (operand1) == HIGH
- && symbolic_operand (XEXP (operand1, 0), mode)))
- {
- int ishighonly = 0;
-
- if (GET_CODE (operand1) == HIGH)
- {
- ishighonly = 1;
- operand1 = XEXP (operand1, 0);
- }
- if (symbolic_operand (operand1, mode))
- {
- /* Argh. The assembler and linker can't handle arithmetic
- involving plabels.
-
- So we force the plabel into memory, load operand0 from
- the memory location, then add in the constant part. */
- if ((GET_CODE (operand1) == CONST
- && GET_CODE (XEXP (operand1, 0)) == PLUS
- && function_label_operand (XEXP (XEXP (operand1, 0), 0), Pmode))
- || function_label_operand (operand1, mode))
- {
- rtx temp, const_part;
-
- /* Figure out what (if any) scratch register to use. */
- if (reload_in_progress || reload_completed)
- scratch_reg = scratch_reg ? scratch_reg : operand0;
- else if (flag_pic)
- scratch_reg = gen_reg_rtx (Pmode);
-
- if (GET_CODE (operand1) == CONST)
- {
- /* Save away the constant part of the expression. */
- const_part = XEXP (XEXP (operand1, 0), 1);
- if (GET_CODE (const_part) != CONST_INT)
- abort ();
-
- /* Force the function label into memory. */
- temp = force_const_mem (mode, XEXP (XEXP (operand1, 0), 0));
- }
- else
- {
- /* No constant part. */
- const_part = NULL_RTX;
-
- /* Force the function label into memory. */
- temp = force_const_mem (mode, operand1);
- }
-
-
- /* Get the address of the memory location. PIC-ify it if
- necessary. */
- temp = XEXP (temp, 0);
- if (flag_pic)
- temp = legitimize_pic_address (temp, mode, scratch_reg);
-
- /* Put the address of the memory location into our destination
- register. */
- operands[1] = temp;
- emit_move_sequence (operands, mode, scratch_reg);
-
- /* Now load from the memory location into our destination
- register. */
- operands[1] = gen_rtx_MEM (Pmode, operands[0]);
- emit_move_sequence (operands, mode, scratch_reg);
-
- /* And add back in the constant part. */
- if (const_part != NULL_RTX)
- expand_inc (operand0, const_part);
-
- return 1;
- }
-
- if (flag_pic)
- {
- rtx temp;
-
- if (reload_in_progress || reload_completed)
- temp = scratch_reg ? scratch_reg : operand0;
- else
- temp = gen_reg_rtx (Pmode);
-
- /* (const (plus (symbol) (const_int))) must be forced to
- memory during/after reload if the const_int will not fit
- in 14 bits. */
- if (GET_CODE (operand1) == CONST
- && GET_CODE (XEXP (operand1, 0)) == PLUS
- && GET_CODE (XEXP (XEXP (operand1, 0), 1)) == CONST_INT
- && !INT_14_BITS (XEXP (XEXP (operand1, 0), 1))
- && (reload_completed || reload_in_progress)
- && flag_pic)
- {
- operands[1] = force_const_mem (mode, operand1);
- operands[1] = legitimize_pic_address (XEXP (operands[1], 0),
- mode, temp);
- emit_move_sequence (operands, mode, temp);
- }
- else
- {
- operands[1] = legitimize_pic_address (operand1, mode, temp);
- emit_insn (gen_rtx_SET (VOIDmode, operand0, operands[1]));
- }
- }
- /* On the HPPA, references to data space are supposed to use dp,
- register 27, but showing it in the RTL inhibits various cse
- and loop optimizations. */
- else
- {
- rtx temp, set;
-
- if (reload_in_progress || reload_completed)
- temp = scratch_reg ? scratch_reg : operand0;
- else
- temp = gen_reg_rtx (mode);
-
- /* Loading a SYMBOL_REF into a register makes that register
- safe to be used as the base in an indexed address.
-
- Don't mark hard registers though. That loses. */
- if (GET_CODE (operand0) == REG
- && REGNO (operand0) >= FIRST_PSEUDO_REGISTER)
- REGNO_POINTER_FLAG (REGNO (operand0)) = 1;
- if (REGNO (temp) >= FIRST_PSEUDO_REGISTER)
- REGNO_POINTER_FLAG (REGNO (temp)) = 1;
- if (ishighonly)
- set = gen_rtx_SET (mode, operand0, temp);
- else
- set = gen_rtx_SET (VOIDmode, operand0,
- gen_rtx_LO_SUM (mode, temp, operand1));
-
- emit_insn (gen_rtx_SET (VOIDmode,
- temp,
- gen_rtx_HIGH (mode, operand1)));
- emit_insn (set);
-
- }
- return 1;
- }
- else if (GET_CODE (operand1) != CONST_INT
- || ! cint_ok_for_move (INTVAL (operand1)))
- {
- rtx temp;
-
- if (reload_in_progress || reload_completed)
- temp = operand0;
- else
- temp = gen_reg_rtx (mode);
-
- emit_insn (gen_rtx_SET (VOIDmode, temp,
- gen_rtx_HIGH (mode, operand1)));
- operands[1] = gen_rtx_LO_SUM (mode, temp, operand1);
- }
- }
- /* Now have insn-emit do whatever it normally does. */
- return 0;
-}
-
-/* Examine EXP and return nonzero if it contains an ADDR_EXPR (meaning
- it will need a link/runtime reloc). */
-
-int
-reloc_needed (exp)
- tree exp;
-{
- int reloc = 0;
-
- switch (TREE_CODE (exp))
- {
- case ADDR_EXPR:
- return 1;
-
- case PLUS_EXPR:
- case MINUS_EXPR:
- reloc = reloc_needed (TREE_OPERAND (exp, 0));
- reloc |= reloc_needed (TREE_OPERAND (exp, 1));
- break;
-
- case NOP_EXPR:
- case CONVERT_EXPR:
- case NON_LVALUE_EXPR:
- reloc = reloc_needed (TREE_OPERAND (exp, 0));
- break;
-
- case CONSTRUCTOR:
- {
- register tree link;
- for (link = CONSTRUCTOR_ELTS (exp); link; link = TREE_CHAIN (link))
- if (TREE_VALUE (link) != 0)
- reloc |= reloc_needed (TREE_VALUE (link));
- }
- break;
-
- case ERROR_MARK:
- break;
-
- default:
- break;
- }
- return reloc;
-}
-
-/* Does operand (which is a symbolic_operand) live in text space? If
- so SYMBOL_REF_FLAG, which is set by ENCODE_SECTION_INFO, will be true. */
-
-int
-read_only_operand (operand)
- rtx operand;
-{
- if (GET_CODE (operand) == CONST)
- operand = XEXP (XEXP (operand, 0), 0);
- if (flag_pic)
- {
- if (GET_CODE (operand) == SYMBOL_REF)
- return SYMBOL_REF_FLAG (operand) && !CONSTANT_POOL_ADDRESS_P (operand);
- }
- else
- {
- if (GET_CODE (operand) == SYMBOL_REF)
- return SYMBOL_REF_FLAG (operand) || CONSTANT_POOL_ADDRESS_P (operand);
- }
- return 1;
-}
-
-
-/* Return the best assembler insn template
- for moving operands[1] into operands[0] as a fullword. */
-char *
-singlemove_string (operands)
- rtx *operands;
-{
- HOST_WIDE_INT intval;
-
- if (GET_CODE (operands[0]) == MEM)
- return "stw %r1,%0";
- if (GET_CODE (operands[1]) == MEM)
- return "ldw %1,%0";
- if (GET_CODE (operands[1]) == CONST_DOUBLE)
- {
- long i;
- REAL_VALUE_TYPE d;
-
- if (GET_MODE (operands[1]) != SFmode)
- abort ();
-
- /* Translate the CONST_DOUBLE to a CONST_INT with the same target
- bit pattern. */
- REAL_VALUE_FROM_CONST_DOUBLE (d, operands[1]);
- REAL_VALUE_TO_TARGET_SINGLE (d, i);
-
- operands[1] = GEN_INT (i);
- /* Fall through to CONST_INT case. */
- }
- if (GET_CODE (operands[1]) == CONST_INT)
- {
- intval = INTVAL (operands[1]);
-
- if (VAL_14_BITS_P (intval))
- return "ldi %1,%0";
- else if ((intval & 0x7ff) == 0)
- return "ldil L'%1,%0";
- else if (zdepi_cint_p (intval))
- return "zdepi %Z1,%0";
- else
- return "ldil L'%1,%0\n\tldo R'%1(%0),%0";
- }
- return "copy %1,%0";
-}
-
-
-/* Compute position (in OP[1]) and width (in OP[2])
- useful for copying IMM to a register using the zdepi
- instructions. Store the immediate value to insert in OP[0]. */
-void
-compute_zdepi_operands (imm, op)
- unsigned HOST_WIDE_INT imm;
- unsigned *op;
-{
- int lsb, len;
-
- /* Find the least significant set bit in IMM. */
- for (lsb = 0; lsb < 32; lsb++)
- {
- if ((imm & 1) != 0)
- break;
- imm >>= 1;
- }
-
- /* Choose variants based on *sign* of the 5-bit field. */
- if ((imm & 0x10) == 0)
- len = (lsb <= 28) ? 4 : 32 - lsb;
- else
- {
- /* Find the width of the bitstring in IMM. */
- for (len = 5; len < 32; len++)
- {
- if ((imm & (1 << len)) == 0)
- break;
- }
-
- /* Sign extend IMM as a 5-bit value. */
- imm = (imm & 0xf) - 0x10;
- }
-
- op[0] = imm;
- op[1] = 31 - lsb;
- op[2] = len;
-}
-
-/* Output assembler code to perform a doubleword move insn
- with operands OPERANDS. */
-
-char *
-output_move_double (operands)
- rtx *operands;
-{
- enum { REGOP, OFFSOP, MEMOP, CNSTOP, RNDOP } optype0, optype1;
- rtx latehalf[2];
- rtx addreg0 = 0, addreg1 = 0;
-
- /* First classify both operands. */
-
- if (REG_P (operands[0]))
- optype0 = REGOP;
- else if (offsettable_memref_p (operands[0]))
- optype0 = OFFSOP;
- else if (GET_CODE (operands[0]) == MEM)
- optype0 = MEMOP;
- else
- optype0 = RNDOP;
-
- if (REG_P (operands[1]))
- optype1 = REGOP;
- else if (CONSTANT_P (operands[1]))
- optype1 = CNSTOP;
- else if (offsettable_memref_p (operands[1]))
- optype1 = OFFSOP;
- else if (GET_CODE (operands[1]) == MEM)
- optype1 = MEMOP;
- else
- optype1 = RNDOP;
-
- /* Check for the cases that the operand constraints are not
- supposed to allow to happen. Abort if we get one,
- because generating code for these cases is painful. */
-
- if (optype0 != REGOP && optype1 != REGOP)
- abort ();
-
- /* Handle auto decrementing and incrementing loads and stores
- specifically, since the structure of the function doesn't work
- for them without major modification. Do it better when we learn
- this port about the general inc/dec addressing of PA.
- (This was written by tege. Chide him if it doesn't work.) */
-
- if (optype0 == MEMOP)
- {
- /* We have to output the address syntax ourselves, since print_operand
- doesn't deal with the addresses we want to use. Fix this later. */
-
- rtx addr = XEXP (operands[0], 0);
- if (GET_CODE (addr) == POST_INC || GET_CODE (addr) == POST_DEC)
- {
- rtx high_reg = gen_rtx_SUBREG (SImode, operands[1], 0);
-
- operands[0] = XEXP (addr, 0);
- if (GET_CODE (operands[1]) != REG || GET_CODE (operands[0]) != REG)
- abort ();
-
- if (!reg_overlap_mentioned_p (high_reg, addr))
- {
- /* No overlap between high target register and address
- register. (We do this in a non-obvious way to
- save a register file writeback) */
- if (GET_CODE (addr) == POST_INC)
- return "stws,ma %1,8(0,%0)\n\tstw %R1,-4(0,%0)";
- return "stws,ma %1,-8(0,%0)\n\tstw %R1,12(0,%0)";
- }
- else
- abort();
- }
- else if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
- {
- rtx high_reg = gen_rtx_SUBREG (SImode, operands[1], 0);
-
- operands[0] = XEXP (addr, 0);
- if (GET_CODE (operands[1]) != REG || GET_CODE (operands[0]) != REG)
- abort ();
-
- if (!reg_overlap_mentioned_p (high_reg, addr))
- {
- /* No overlap between high target register and address
- register. (We do this in a non-obvious way to
- save a register file writeback) */
- if (GET_CODE (addr) == PRE_INC)
- return "stws,mb %1,8(0,%0)\n\tstw %R1,4(0,%0)";
- return "stws,mb %1,-8(0,%0)\n\tstw %R1,4(0,%0)";
- }
- else
- abort();
- }
- }
- if (optype1 == MEMOP)
- {
- /* We have to output the address syntax ourselves, since print_operand
- doesn't deal with the addresses we want to use. Fix this later. */
-
- rtx addr = XEXP (operands[1], 0);
- if (GET_CODE (addr) == POST_INC || GET_CODE (addr) == POST_DEC)
- {
- rtx high_reg = gen_rtx_SUBREG (SImode, operands[0], 0);
-
- operands[1] = XEXP (addr, 0);
- if (GET_CODE (operands[0]) != REG || GET_CODE (operands[1]) != REG)
- abort ();
-
- if (!reg_overlap_mentioned_p (high_reg, addr))
- {
- /* No overlap between high target register and address
- register. (We do this in a non-obvious way to
- save a register file writeback) */
- if (GET_CODE (addr) == POST_INC)
- return "ldws,ma 8(0,%1),%0\n\tldw -4(0,%1),%R0";
- return "ldws,ma -8(0,%1),%0\n\tldw 12(0,%1),%R0";
- }
- else
- {
- /* This is an undefined situation. We should load into the
- address register *and* update that register. Probably
- we don't need to handle this at all. */
- if (GET_CODE (addr) == POST_INC)
- return "ldw 4(0,%1),%R0\n\tldws,ma 8(0,%1),%0";
- return "ldw 4(0,%1),%R0\n\tldws,ma -8(0,%1),%0";
- }
- }
- else if (GET_CODE (addr) == PRE_INC || GET_CODE (addr) == PRE_DEC)
- {
- rtx high_reg = gen_rtx_SUBREG (SImode, operands[0], 0);
-
- operands[1] = XEXP (addr, 0);
- if (GET_CODE (operands[0]) != REG || GET_CODE (operands[1]) != REG)
- abort ();
-
- if (!reg_overlap_mentioned_p (high_reg, addr))
- {
- /* No overlap between high target register and address
- register. (We do this in a non-obvious way to
- save a register file writeback) */
- if (GET_CODE (addr) == PRE_INC)
- return "ldws,mb 8(0,%1),%0\n\tldw 4(0,%1),%R0";
- return "ldws,mb -8(0,%1),%0\n\tldw 4(0,%1),%R0";
- }
- else
- {
- /* This is an undefined situation. We should load into the
- address register *and* update that register. Probably
- we don't need to handle this at all. */
- if (GET_CODE (addr) == PRE_INC)
- return "ldw 12(0,%1),%R0\n\tldws,mb 8(0,%1),%0";
- return "ldw -4(0,%1),%R0\n\tldws,mb -8(0,%1),%0";
- }
- }
- else if (GET_CODE (addr) == PLUS
- && GET_CODE (XEXP (addr, 0)) == MULT)
- {
- rtx high_reg = gen_rtx_SUBREG (SImode, operands[0], 0);
-
- if (!reg_overlap_mentioned_p (high_reg, addr))
- {
- rtx xoperands[3];
-
- xoperands[0] = high_reg;
- xoperands[1] = XEXP (addr, 1);
- xoperands[2] = XEXP (XEXP (addr, 0), 0);
- xoperands[3] = XEXP (XEXP (addr, 0), 1);
- output_asm_insn ("sh%O3addl %2,%1,%0", xoperands);
- return "ldw 4(0,%0),%R0\n\tldw 0(0,%0),%0";
- }
- else
- {
- rtx xoperands[3];
-
- xoperands[0] = high_reg;
- xoperands[1] = XEXP (addr, 1);
- xoperands[2] = XEXP (XEXP (addr, 0), 0);
- xoperands[3] = XEXP (XEXP (addr, 0), 1);
- output_asm_insn ("sh%O3addl %2,%1,%R0", xoperands);
- return "ldw 0(0,%R0),%0\n\tldw 4(0,%R0),%R0";
- }
-
- }
- }
-
- /* If an operand is an unoffsettable memory ref, find a register
- we can increment temporarily to make it refer to the second word. */
-
- if (optype0 == MEMOP)
- addreg0 = find_addr_reg (XEXP (operands[0], 0));
-
- if (optype1 == MEMOP)
- addreg1 = find_addr_reg (XEXP (operands[1], 0));
-
- /* Ok, we can do one word at a time.
- Normally we do the low-numbered word first.
-
- In either case, set up in LATEHALF the operands to use
- for the high-numbered word and in some cases alter the
- operands in OPERANDS to be suitable for the low-numbered word. */
-
- if (optype0 == REGOP)
- latehalf[0] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
- else if (optype0 == OFFSOP)
- latehalf[0] = adj_offsettable_operand (operands[0], 4);
- else
- latehalf[0] = operands[0];
-
- if (optype1 == REGOP)
- latehalf[1] = gen_rtx_REG (SImode, REGNO (operands[1]) + 1);
- else if (optype1 == OFFSOP)
- latehalf[1] = adj_offsettable_operand (operands[1], 4);
- else if (optype1 == CNSTOP)
- split_double (operands[1], &operands[1], &latehalf[1]);
- else
- latehalf[1] = operands[1];
-
- /* If the first move would clobber the source of the second one,
- do them in the other order.
-
- This can happen in two cases:
-
- mem -> register where the first half of the destination register
- is the same register used in the memory's address. Reload
- can create such insns.
-
- mem in this case will be either register indirect or register
- indirect plus a valid offset.
-
- register -> register move where REGNO(dst) == REGNO(src + 1)
- someone (Tim/Tege?) claimed this can happen for parameter loads.
-
- Handle mem -> register case first. */
- if (optype0 == REGOP
- && (optype1 == MEMOP || optype1 == OFFSOP)
- && refers_to_regno_p (REGNO (operands[0]), REGNO (operands[0]) + 1,
- operands[1], 0))
- {
- /* Do the late half first. */
- if (addreg1)
- output_asm_insn ("ldo 4(%0),%0", &addreg1);
- output_asm_insn (singlemove_string (latehalf), latehalf);
-
- /* Then clobber. */
- if (addreg1)
- output_asm_insn ("ldo -4(%0),%0", &addreg1);
- return singlemove_string (operands);
- }
-
- /* Now handle register -> register case. */
- if (optype0 == REGOP && optype1 == REGOP
- && REGNO (operands[0]) == REGNO (operands[1]) + 1)
- {
- output_asm_insn (singlemove_string (latehalf), latehalf);
- return singlemove_string (operands);
- }
-
- /* Normal case: do the two words, low-numbered first. */
-
- output_asm_insn (singlemove_string (operands), operands);
-
- /* Make any unoffsettable addresses point at high-numbered word. */
- if (addreg0)
- output_asm_insn ("ldo 4(%0),%0", &addreg0);
- if (addreg1)
- output_asm_insn ("ldo 4(%0),%0", &addreg1);
-
- /* Do that word. */
- output_asm_insn (singlemove_string (latehalf), latehalf);
-
- /* Undo the adds we just did. */
- if (addreg0)
- output_asm_insn ("ldo -4(%0),%0", &addreg0);
- if (addreg1)
- output_asm_insn ("ldo -4(%0),%0", &addreg1);
-
- return "";
-}
-
-char *
-output_fp_move_double (operands)
- rtx *operands;
-{
- if (FP_REG_P (operands[0]))
- {
- if (FP_REG_P (operands[1])
- || operands[1] == CONST0_RTX (GET_MODE (operands[0])))
- output_asm_insn ("fcpy,dbl %r1,%0", operands);
- else
- output_asm_insn ("fldd%F1 %1,%0", operands);
- }
- else if (FP_REG_P (operands[1]))
- {
- output_asm_insn ("fstd%F0 %1,%0", operands);
- }
- else if (operands[1] == CONST0_RTX (GET_MODE (operands[0])))
- {
- if (GET_CODE (operands[0]) == REG)
- {
- rtx xoperands[2];
- xoperands[1] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
- xoperands[0] = operands[0];
- output_asm_insn ("copy %%r0,%0\n\tcopy %%r0,%1", xoperands);
- }
- /* This is a pain. You have to be prepared to deal with an
- arbitrary address here including pre/post increment/decrement.
-
- so avoid this in the MD. */
- else
- abort ();
- }
- else abort ();
- return "";
-}
-
-/* Return a REG that occurs in ADDR with coefficient 1.
- ADDR can be effectively incremented by incrementing REG. */
-
-static rtx
-find_addr_reg (addr)
- rtx addr;
-{
- while (GET_CODE (addr) == PLUS)
- {
- if (GET_CODE (XEXP (addr, 0)) == REG)
- addr = XEXP (addr, 0);
- else if (GET_CODE (XEXP (addr, 1)) == REG)
- addr = XEXP (addr, 1);
- else if (CONSTANT_P (XEXP (addr, 0)))
- addr = XEXP (addr, 1);
- else if (CONSTANT_P (XEXP (addr, 1)))
- addr = XEXP (addr, 0);
- else
- abort ();
- }
- if (GET_CODE (addr) == REG)
- return addr;
- abort ();
-}
-
-/* Emit code to perform a block move.
-
- OPERANDS[0] is the destination pointer as a REG, clobbered.
- OPERANDS[1] is the source pointer as a REG, clobbered.
- OPERANDS[2] is a register for temporary storage.
- OPERANDS[4] is the size as a CONST_INT
- OPERANDS[3] is a register for temporary storage.
- OPERANDS[5] is the alignment safe to use, as a CONST_INT.
- OPERANDS[6] is another temporary register. */
-
-char *
-output_block_move (operands, size_is_constant)
- rtx *operands;
- int size_is_constant ATTRIBUTE_UNUSED;
-{
- int align = INTVAL (operands[5]);
- unsigned long n_bytes = INTVAL (operands[4]);
-
- /* We can't move more than four bytes at a time because the PA
- has no longer integer move insns. (Could use fp mem ops?) */
- if (align > 4)
- align = 4;
-
- /* Note that we know each loop below will execute at least twice
- (else we would have open-coded the copy). */
- switch (align)
- {
- case 4:
- /* Pre-adjust the loop counter. */
- operands[4] = GEN_INT (n_bytes - 8);
- output_asm_insn ("ldi %4,%2", operands);
-
- /* Copying loop. */
- output_asm_insn ("ldws,ma 4(0,%1),%3", operands);
- output_asm_insn ("ldws,ma 4(0,%1),%6", operands);
- output_asm_insn ("stws,ma %3,4(0,%0)", operands);
- output_asm_insn ("addib,>= -8,%2,.-12", operands);
- output_asm_insn ("stws,ma %6,4(0,%0)", operands);
-
- /* Handle the residual. There could be up to 7 bytes of
- residual to copy! */
- if (n_bytes % 8 != 0)
- {
- operands[4] = GEN_INT (n_bytes % 4);
- if (n_bytes % 8 >= 4)
- output_asm_insn ("ldws,ma 4(0,%1),%3", operands);
- if (n_bytes % 4 != 0)
- output_asm_insn ("ldw 0(0,%1),%6", operands);
- if (n_bytes % 8 >= 4)
- output_asm_insn ("stws,ma %3,4(0,%0)", operands);
- if (n_bytes % 4 != 0)
- output_asm_insn ("stbys,e %6,%4(0,%0)", operands);
- }
- return "";
-
- case 2:
- /* Pre-adjust the loop counter. */
- operands[4] = GEN_INT (n_bytes - 4);
- output_asm_insn ("ldi %4,%2", operands);
-
- /* Copying loop. */
- output_asm_insn ("ldhs,ma 2(0,%1),%3", operands);
- output_asm_insn ("ldhs,ma 2(0,%1),%6", operands);
- output_asm_insn ("sths,ma %3,2(0,%0)", operands);
- output_asm_insn ("addib,>= -4,%2,.-12", operands);
- output_asm_insn ("sths,ma %6,2(0,%0)", operands);
-
- /* Handle the residual. */
- if (n_bytes % 4 != 0)
- {
- if (n_bytes % 4 >= 2)
- output_asm_insn ("ldhs,ma 2(0,%1),%3", operands);
- if (n_bytes % 2 != 0)
- output_asm_insn ("ldb 0(0,%1),%6", operands);
- if (n_bytes % 4 >= 2)
- output_asm_insn ("sths,ma %3,2(0,%0)", operands);
- if (n_bytes % 2 != 0)
- output_asm_insn ("stb %6,0(0,%0)", operands);
- }
- return "";
-
- case 1:
- /* Pre-adjust the loop counter. */
- operands[4] = GEN_INT (n_bytes - 2);
- output_asm_insn ("ldi %4,%2", operands);
-
- /* Copying loop. */
- output_asm_insn ("ldbs,ma 1(0,%1),%3", operands);
- output_asm_insn ("ldbs,ma 1(0,%1),%6", operands);
- output_asm_insn ("stbs,ma %3,1(0,%0)", operands);
- output_asm_insn ("addib,>= -2,%2,.-12", operands);
- output_asm_insn ("stbs,ma %6,1(0,%0)", operands);
-
- /* Handle the residual. */
- if (n_bytes % 2 != 0)
- {
- output_asm_insn ("ldb 0(0,%1),%3", operands);
- output_asm_insn ("stb %3,0(0,%0)", operands);
- }
- return "";
-
- default:
- abort ();
- }
-}
-
-/* Count the number of insns necessary to handle this block move.
-
- Basic structure is the same as emit_block_move, except that we
- count insns rather than emit them. */
-
-int
-compute_movstrsi_length (insn)
- rtx insn;
-{
- rtx pat = PATTERN (insn);
- int align = INTVAL (XEXP (XVECEXP (pat, 0, 6), 0));
- unsigned long n_bytes = INTVAL (XEXP (XVECEXP (pat, 0, 5), 0));
- unsigned int n_insns = 0;
-
- /* We can't move more than four bytes at a time because the PA
- has no longer integer move insns. (Could use fp mem ops?) */
- if (align > 4)
- align = 4;
-
- /* The basic copying loop. */
- n_insns = 6;
-
- /* Residuals. */
- if (n_bytes % (2 * align) != 0)
- {
- if ((n_bytes % (2 * align)) >= align)
- n_insns += 2;
-
- if ((n_bytes % align) != 0)
- n_insns += 2;
- }
-
- /* Lengths are expressed in bytes now; each insn is 4 bytes. */
- return n_insns * 4;
-}
-
-
-char *
-output_and (operands)
- rtx *operands;
-{
- if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) != 0)
- {
- unsigned HOST_WIDE_INT mask = INTVAL (operands[2]);
- int ls0, ls1, ms0, p, len;
-
- for (ls0 = 0; ls0 < 32; ls0++)
- if ((mask & (1 << ls0)) == 0)
- break;
-
- for (ls1 = ls0; ls1 < 32; ls1++)
- if ((mask & (1 << ls1)) != 0)
- break;
-
- for (ms0 = ls1; ms0 < 32; ms0++)
- if ((mask & (1 << ms0)) == 0)
- break;
-
- if (ms0 != 32)
- abort();
-
- if (ls1 == 32)
- {
- len = ls0;
-
- if (len == 0)
- abort ();
-
- operands[2] = GEN_INT (len);
- return "extru %1,31,%2,%0";
- }
- else
- {
- /* We could use this `depi' for the case above as well, but `depi'
- requires one more register file access than an `extru'. */
-
- p = 31 - ls0;
- len = ls1 - ls0;
-
- operands[2] = GEN_INT (p);
- operands[3] = GEN_INT (len);
- return "depi 0,%2,%3,%0";
- }
- }
- else
- return "and %1,%2,%0";
-}
-
-char *
-output_ior (operands)
- rtx *operands;
-{
- unsigned HOST_WIDE_INT mask = INTVAL (operands[2]);
- int bs0, bs1, p, len;
-
- if (INTVAL (operands[2]) == 0)
- return "copy %1,%0";
-
- for (bs0 = 0; bs0 < 32; bs0++)
- if ((mask & (1 << bs0)) != 0)
- break;
-
- for (bs1 = bs0; bs1 < 32; bs1++)
- if ((mask & (1 << bs1)) == 0)
- break;
-
- if (bs1 != 32 && ((unsigned HOST_WIDE_INT) 1 << bs1) <= mask)
- abort();
-
- p = 31 - bs0;
- len = bs1 - bs0;
-
- operands[2] = GEN_INT (p);
- operands[3] = GEN_INT (len);
- return "depi -1,%2,%3,%0";
-}
-
-/* Output an ascii string. */
-void
-output_ascii (file, p, size)
- FILE *file;
- unsigned char *p;
- int size;
-{
- int i;
- int chars_output;
- unsigned char partial_output[16]; /* Max space 4 chars can occupy. */
-
- /* The HP assembler can only take strings of 256 characters at one
- time. This is a limitation on input line length, *not* the
- length of the string. Sigh. Even worse, it seems that the
- restriction is in number of input characters (see \xnn &
- \whatever). So we have to do this very carefully. */
-
- fputs ("\t.STRING \"", file);
-
- chars_output = 0;
- for (i = 0; i < size; i += 4)
- {
- int co = 0;
- int io = 0;
- for (io = 0, co = 0; io < MIN (4, size - i); io++)
- {
- register unsigned int c = p[i + io];
-
- if (c == '\"' || c == '\\')
- partial_output[co++] = '\\';
- if (c >= ' ' && c < 0177)
- partial_output[co++] = c;
- else
- {
- unsigned int hexd;
- partial_output[co++] = '\\';
- partial_output[co++] = 'x';
- hexd = c / 16 - 0 + '0';
- if (hexd > '9')
- hexd -= '9' - 'a' + 1;
- partial_output[co++] = hexd;
- hexd = c % 16 - 0 + '0';
- if (hexd > '9')
- hexd -= '9' - 'a' + 1;
- partial_output[co++] = hexd;
- }
- }
- if (chars_output + co > 243)
- {
- fputs ("\"\n\t.STRING \"", file);
- chars_output = 0;
- }
- fwrite (partial_output, 1, co, file);
- chars_output += co;
- co = 0;
- }
- fputs ("\"\n", file);
-}
-
-/* Try to rewrite floating point comparisons & branches to avoid
- useless add,tr insns.
-
- CHECK_NOTES is nonzero if we should examine REG_DEAD notes
- to see if FPCC is dead. CHECK_NOTES is nonzero for the
- first attempt to remove useless add,tr insns. It is zero
- for the second pass as reorg sometimes leaves bogus REG_DEAD
- notes lying around.
-
- When CHECK_NOTES is zero we can only eliminate add,tr insns
- when there's a 1:1 correspondence between fcmp and ftest/fbranch
- instructions. */
-void
-remove_useless_addtr_insns (insns, check_notes)
- rtx insns;
- int check_notes;
-{
- rtx insn;
- static int pass = 0;
-
- /* This is fairly cheap, so always run it when optimizing. */
- if (optimize > 0)
- {
- int fcmp_count = 0;
- int fbranch_count = 0;
-
- /* Walk all the insns in this function looking for fcmp & fbranch
- instructions. Keep track of how many of each we find. */
- insns = get_insns ();
- for (insn = insns; insn; insn = next_insn (insn))
- {
- rtx tmp;
-
- /* Ignore anything that isn't an INSN or a JUMP_INSN. */
- if (GET_CODE (insn) != INSN && GET_CODE (insn) != JUMP_INSN)
- continue;
-
- tmp = PATTERN (insn);
-
- /* It must be a set. */
- if (GET_CODE (tmp) != SET)
- continue;
-
- /* If the destination is CCFP, then we've found an fcmp insn. */
- tmp = SET_DEST (tmp);
- if (GET_CODE (tmp) == REG && REGNO (tmp) == 0)
- {
- fcmp_count++;
- continue;
- }
-
- tmp = PATTERN (insn);
- /* If this is an fbranch instruction, bump the fbranch counter. */
- if (GET_CODE (tmp) == SET
- && SET_DEST (tmp) == pc_rtx
- && GET_CODE (SET_SRC (tmp)) == IF_THEN_ELSE
- && GET_CODE (XEXP (SET_SRC (tmp), 0)) == NE
- && GET_CODE (XEXP (XEXP (SET_SRC (tmp), 0), 0)) == REG
- && REGNO (XEXP (XEXP (SET_SRC (tmp), 0), 0)) == 0)
- {
- fbranch_count++;
- continue;
- }
- }
-
-
- /* Find all floating point compare + branch insns. If possible,
- reverse the comparison & the branch to avoid add,tr insns. */
- for (insn = insns; insn; insn = next_insn (insn))
- {
- rtx tmp, next;
-
- /* Ignore anything that isn't an INSN. */
- if (GET_CODE (insn) != INSN)
- continue;
-
- tmp = PATTERN (insn);
-
- /* It must be a set. */
- if (GET_CODE (tmp) != SET)
- continue;
-
- /* The destination must be CCFP, which is register zero. */
- tmp = SET_DEST (tmp);
- if (GET_CODE (tmp) != REG || REGNO (tmp) != 0)
- continue;
-
- /* INSN should be a set of CCFP.
-
- See if the result of this insn is used in a reversed FP
- conditional branch. If so, reverse our condition and
- the branch. Doing so avoids useless add,tr insns. */
- next = next_insn (insn);
- while (next)
- {
- /* Jumps, calls and labels stop our search. */
- if (GET_CODE (next) == JUMP_INSN
- || GET_CODE (next) == CALL_INSN
- || GET_CODE (next) == CODE_LABEL)
- break;
-
- /* As does another fcmp insn. */
- if (GET_CODE (next) == INSN
- && GET_CODE (PATTERN (next)) == SET
- && GET_CODE (SET_DEST (PATTERN (next))) == REG
- && REGNO (SET_DEST (PATTERN (next))) == 0)
- break;
-
- next = next_insn (next);
- }
-
- /* Is NEXT_INSN a branch? */
- if (next
- && GET_CODE (next) == JUMP_INSN)
- {
- rtx pattern = PATTERN (next);
-
- /* If it a reversed fp conditional branch (eg uses add,tr)
- and CCFP dies, then reverse our conditional and the branch
- to avoid the add,tr. */
- if (GET_CODE (pattern) == SET
- && SET_DEST (pattern) == pc_rtx
- && GET_CODE (SET_SRC (pattern)) == IF_THEN_ELSE
- && GET_CODE (XEXP (SET_SRC (pattern), 0)) == NE
- && GET_CODE (XEXP (XEXP (SET_SRC (pattern), 0), 0)) == REG
- && REGNO (XEXP (XEXP (SET_SRC (pattern), 0), 0)) == 0
- && GET_CODE (XEXP (SET_SRC (pattern), 1)) == PC
- && (fcmp_count == fbranch_count
- || (check_notes
- && find_regno_note (next, REG_DEAD, 0))))
- {
- /* Reverse the branch. */
- tmp = XEXP (SET_SRC (pattern), 1);
- XEXP (SET_SRC (pattern), 1) = XEXP (SET_SRC (pattern), 2);
- XEXP (SET_SRC (pattern), 2) = tmp;
- INSN_CODE (next) = -1;
-
- /* Reverse our condition. */
- tmp = PATTERN (insn);
- PUT_CODE (XEXP (tmp, 1),
- reverse_condition (GET_CODE (XEXP (tmp, 1))));
- }
- }
- }
- }
-
- pass = !pass;
-
-}
-
-/* You may have trouble believing this, but this is the HP-PA stack
- layout. Wow.
-
- Offset Contents
-
- Variable arguments (optional; any number may be allocated)
-
- SP-(4*(N+9)) arg word N
- : :
- SP-56 arg word 5
- SP-52 arg word 4
-
- Fixed arguments (must be allocated; may remain unused)
-
- SP-48 arg word 3
- SP-44 arg word 2
- SP-40 arg word 1
- SP-36 arg word 0
-
- Frame Marker
-
- SP-32 External Data Pointer (DP)
- SP-28 External sr4
- SP-24 External/stub RP (RP')
- SP-20 Current RP
- SP-16 Static Link
- SP-12 Clean up
- SP-8 Calling Stub RP (RP'')
- SP-4 Previous SP
-
- Top of Frame
-
- SP-0 Stack Pointer (points to next available address)
-
-*/
-
-/* This function saves registers as follows. Registers marked with ' are
- this function's registers (as opposed to the previous function's).
- If a frame_pointer isn't needed, r4 is saved as a general register;
- the space for the frame pointer is still allocated, though, to keep
- things simple.
-
-
- Top of Frame
-
- SP (FP') Previous FP
- SP + 4 Alignment filler (sigh)
- SP + 8 Space for locals reserved here.
- .
- .
- .
- SP + n All call saved register used.
- .
- .
- .
- SP + o All call saved fp registers used.
- .
- .
- .
- SP + p (SP') points to next available address.
-
-*/
-
-/* Emit RTL to store REG at the memory location specified by BASE+DISP.
- Handle case where DISP > 8k by using the add_high_const pattern.
-
- Note in DISP > 8k case, we will leave the high part of the address
- in %r1. There is code in expand_hppa_{prologue,epilogue} that knows this.*/
-static void
-store_reg (reg, disp, base)
- int reg, disp, base;
-{
- if (VAL_14_BITS_P (disp))
- {
- emit_move_insn (gen_rtx_MEM (SImode,
- gen_rtx_PLUS (SImode,
- gen_rtx_REG (SImode, base),
- GEN_INT (disp))),
- gen_rtx_REG (SImode, reg));
- }
- else
- {
- emit_insn (gen_add_high_const (gen_rtx_REG (SImode, 1),
- gen_rtx_REG (SImode, base),
- GEN_INT (disp)));
- emit_move_insn (gen_rtx_MEM (SImode,
- gen_rtx_LO_SUM (SImode,
- gen_rtx_REG (SImode, 1),
- GEN_INT (disp))),
- gen_rtx_REG (SImode, reg));
- }
-}
-
-/* Emit RTL to load REG from the memory location specified by BASE+DISP.
- Handle case where DISP > 8k by using the add_high_const pattern.
-
- Note in DISP > 8k case, we will leave the high part of the address
- in %r1. There is code in expand_hppa_{prologue,epilogue} that knows this.*/
-static void
-load_reg (reg, disp, base)
- int reg, disp, base;
-{
- if (VAL_14_BITS_P (disp))
- {
- emit_move_insn (gen_rtx_REG (SImode, reg),
- gen_rtx_MEM (SImode,
- gen_rtx_PLUS (SImode,
- gen_rtx_REG (SImode, base),
- GEN_INT (disp))));
- }
- else
- {
- emit_insn (gen_add_high_const (gen_rtx_REG (SImode, 1),
- gen_rtx_REG (SImode, base),
- GEN_INT (disp)));
- emit_move_insn (gen_rtx_REG (SImode, reg),
- gen_rtx_MEM (SImode,
- gen_rtx_LO_SUM (SImode,
- gen_rtx_REG (SImode, 1),
- GEN_INT (disp))));
- }
-}
-
-/* Emit RTL to set REG to the value specified by BASE+DISP.
- Handle case where DISP > 8k by using the add_high_const pattern.
-
- Note in DISP > 8k case, we will leave the high part of the address
- in %r1. There is code in expand_hppa_{prologue,epilogue} that knows this.*/
-static void
-set_reg_plus_d(reg, base, disp)
- int reg, base, disp;
-{
- if (VAL_14_BITS_P (disp))
- {
- emit_move_insn (gen_rtx_REG (SImode, reg),
- gen_rtx_PLUS (SImode,
- gen_rtx_REG (SImode, base),
- GEN_INT (disp)));
- }
- else
- {
- emit_insn (gen_add_high_const (gen_rtx_REG (SImode, 1),
- gen_rtx_REG (SImode, base),
- GEN_INT (disp)));
- emit_move_insn (gen_rtx_REG (SImode, reg),
- gen_rtx_LO_SUM (SImode,
- gen_rtx_REG (SImode, 1),
- GEN_INT (disp)));
- }
-}
-
-/* Global variables set by FUNCTION_PROLOGUE. */
-/* Size of frame. Need to know this to emit return insns from
- leaf procedures. */
-static int actual_fsize;
-static int local_fsize, save_fregs;
-
-int
-compute_frame_size (size, fregs_live)
- int size;
- int *fregs_live;
-{
- extern int current_function_outgoing_args_size;
- int i, fsize;
-
- /* 8 is space for frame pointer + filler. If any frame is allocated
- we need to add this in because of STARTING_FRAME_OFFSET. */
- fsize = size + (size || frame_pointer_needed ? 8 : 0);
-
- /* We must leave enough space for all the callee saved registers
- from 3 .. highest used callee save register since we don't
- know if we're going to have an inline or out of line prologue
- and epilogue. */
- for (i = 18; i >= 3; i--)
- if (regs_ever_live[i])
- {
- fsize += 4 * (i - 2);
- break;
- }
-
- /* Round the stack. */
- fsize = (fsize + 7) & ~7;
-
- /* We must leave enough space for all the callee saved registers
- from 3 .. highest used callee save register since we don't
- know if we're going to have an inline or out of line prologue
- and epilogue. */
- for (i = 66; i >= 48; i -= 2)
- if (regs_ever_live[i] || regs_ever_live[i + 1])
- {
- if (fregs_live)
- *fregs_live = 1;
-
- fsize += 4 * (i - 46);
- break;
- }
-
- fsize += current_function_outgoing_args_size;
- if (! leaf_function_p () || fsize)
- fsize += 32;
- return (fsize + 63) & ~63;
-}
-
-rtx hp_profile_label_rtx;
-static char hp_profile_label_name[8];
-void
-output_function_prologue (file, size)
- FILE *file;
- int size ATTRIBUTE_UNUSED;
-{
- /* The function's label and associated .PROC must never be
- separated and must be output *after* any profiling declarations
- to avoid changing spaces/subspaces within a procedure. */
- ASM_OUTPUT_LABEL (file, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));
- fputs ("\t.PROC\n", file);
-
- /* hppa_expand_prologue does the dirty work now. We just need
- to output the assembler directives which denote the start
- of a function. */
- fprintf (file, "\t.CALLINFO FRAME=%d", actual_fsize);
- if (regs_ever_live[2] || profile_flag)
- fputs (",CALLS,SAVE_RP", file);
- else
- fputs (",NO_CALLS", file);
-
- if (frame_pointer_needed)
- fputs (",SAVE_SP", file);
-
- /* Pass on information about the number of callee register saves
- performed in the prologue.
-
- The compiler is supposed to pass the highest register number
- saved, the assembler then has to adjust that number before
- entering it into the unwind descriptor (to account for any
- caller saved registers with lower register numbers than the
- first callee saved register). */
- if (gr_saved)
- fprintf (file, ",ENTRY_GR=%d", gr_saved + 2);
-
- if (fr_saved)
- fprintf (file, ",ENTRY_FR=%d", fr_saved + 11);
-
- fputs ("\n\t.ENTRY\n", file);
-
- /* Horrid hack. emit_function_prologue will modify this RTL in
- place to get the expected results. */
- if (profile_flag)
- ASM_GENERATE_INTERNAL_LABEL (hp_profile_label_name, "LP",
- hp_profile_labelno);
-
- /* If we're using GAS and not using the portable runtime model, then
- we don't need to accumulate the total number of code bytes. */
- if (TARGET_GAS && ! TARGET_PORTABLE_RUNTIME)
- total_code_bytes = 0;
- else if (insn_addresses)
- {
- unsigned int old_total = total_code_bytes;
-
- total_code_bytes += insn_addresses[INSN_UID (get_last_insn())];
- total_code_bytes += FUNCTION_BOUNDARY / BITS_PER_UNIT;
-
- /* Be prepared to handle overflows. */
- total_code_bytes = old_total > total_code_bytes ? -1 : total_code_bytes;
- }
- else
- total_code_bytes = -1;
-
- remove_useless_addtr_insns (get_insns (), 0);
-
- /* Restore INSN_CODEs for insn which use unscaled indexed addresses. */
- restore_unscaled_index_insn_codes (get_insns ());
-}
-
-void
-hppa_expand_prologue()
-{
- extern char call_used_regs[];
- int size = get_frame_size ();
- int merge_sp_adjust_with_store = 0;
- int i, offset;
- rtx tmpreg, size_rtx;
-
- gr_saved = 0;
- fr_saved = 0;
- save_fregs = 0;
- local_fsize = size + (size || frame_pointer_needed ? 8 : 0);
- actual_fsize = compute_frame_size (size, &save_fregs);
-
- /* Compute a few things we will use often. */
- tmpreg = gen_rtx_REG (SImode, 1);
- size_rtx = GEN_INT (actual_fsize);
-
- /* Handle out of line prologues and epilogues. */
- if (TARGET_SPACE)
- {
- rtx operands[2];
- int saves = 0;
- int outline_insn_count = 0;
- int inline_insn_count = 0;
-
- /* Count the number of insns for the inline and out of line
- variants so we can choose one appropriately.
-
- No need to screw with counting actual_fsize operations -- they're
- done for both inline and out of line prologues. */
- if (regs_ever_live[2])
- inline_insn_count += 1;
-
- if (! cint_ok_for_move (local_fsize))
- outline_insn_count += 2;
- else
- outline_insn_count += 1;
-
- /* Put the register save info into %r22. */
- for (i = 18; i >= 3; i--)
- if (regs_ever_live[i] && ! call_used_regs[i])
- {
- /* -1 because the stack adjustment is normally done in
- the same insn as a register save. */
- inline_insn_count += (i - 2) - 1;
- saves = i;
- break;
- }
-
- for (i = 66; i >= 48; i -= 2)
- if (regs_ever_live[i] || regs_ever_live[i + 1])
- {
- /* +1 needed as we load %r1 with the start of the freg
- save area. */
- inline_insn_count += (i/2 - 23) + 1;
- saves |= ((i/2 - 12 ) << 16);
- break;
- }
-
- if (frame_pointer_needed)
- inline_insn_count += 3;
-
- if (! cint_ok_for_move (saves))
- outline_insn_count += 2;
- else
- outline_insn_count += 1;
-
- if (TARGET_PORTABLE_RUNTIME)
- outline_insn_count += 2;
- else
- outline_insn_count += 1;
-
- /* If there's a lot of insns in the prologue, then do it as
- an out-of-line sequence. */
- if (inline_insn_count > outline_insn_count)
- {
- /* Put the local_fisze into %r19. */
- operands[0] = gen_rtx_REG (SImode, 19);
- operands[1] = GEN_INT (local_fsize);
- emit_move_insn (operands[0], operands[1]);
-
- /* Put the stack size into %r21. */
- operands[0] = gen_rtx_REG (SImode, 21);
- operands[1] = size_rtx;
- emit_move_insn (operands[0], operands[1]);
-
- operands[0] = gen_rtx_REG (SImode, 22);
- operands[1] = GEN_INT (saves);
- emit_move_insn (operands[0], operands[1]);
-
- /* Now call the out-of-line prologue. */
- emit_insn (gen_outline_prologue_call ());
- emit_insn (gen_blockage ());
-
- /* Note that we're using an out-of-line prologue. */
- out_of_line_prologue_epilogue = 1;
- return;
- }
- }
-
- out_of_line_prologue_epilogue = 0;
-
- /* Save RP first. The calling conventions manual states RP will
- always be stored into the caller's frame at sp-20. */
- if (regs_ever_live[2] || profile_flag)
- store_reg (2, -20, STACK_POINTER_REGNUM);
-
- /* Allocate the local frame and set up the frame pointer if needed. */
- if (actual_fsize)
- {
- if (frame_pointer_needed)
- {
- /* Copy the old frame pointer temporarily into %r1. Set up the
- new stack pointer, then store away the saved old frame pointer
- into the stack at sp+actual_fsize and at the same time update
- the stack pointer by actual_fsize bytes. Two versions, first
- handles small (<8k) frames. The second handles large (>8k)
- frames. */
- emit_move_insn (tmpreg, frame_pointer_rtx);
- emit_move_insn (frame_pointer_rtx, stack_pointer_rtx);
- if (VAL_14_BITS_P (actual_fsize))
- emit_insn (gen_post_stwm (stack_pointer_rtx, tmpreg, size_rtx));
- else
- {
- /* It is incorrect to store the saved frame pointer at *sp,
- then increment sp (writes beyond the current stack boundary).
-
- So instead use stwm to store at *sp and post-increment the
- stack pointer as an atomic operation. Then increment sp to
- finish allocating the new frame. */
- emit_insn (gen_post_stwm (stack_pointer_rtx, tmpreg, GEN_INT (64)));
- set_reg_plus_d (STACK_POINTER_REGNUM,
- STACK_POINTER_REGNUM,
- actual_fsize - 64);
- }
- }
- /* no frame pointer needed. */
- else
- {
- /* In some cases we can perform the first callee register save
- and allocating the stack frame at the same time. If so, just
- make a note of it and defer allocating the frame until saving
- the callee registers. */
- if (VAL_14_BITS_P (-actual_fsize)
- && local_fsize == 0
- && ! profile_flag
- && ! flag_pic)
- merge_sp_adjust_with_store = 1;
- /* Can not optimize. Adjust the stack frame by actual_fsize bytes. */
- else if (actual_fsize != 0)
- set_reg_plus_d (STACK_POINTER_REGNUM,
- STACK_POINTER_REGNUM,
- actual_fsize);
- }
- }
-
- /* The hppa calling conventions say that %r19, the pic offset
- register, is saved at sp - 32 (in this function's frame) when
- generating PIC code. FIXME: What is the correct thing to do
- for functions which make no calls and allocate no frame? Do
- we need to allocate a frame, or can we just omit the save? For
- now we'll just omit the save. */
- if (actual_fsize != 0 && flag_pic)
- store_reg (PIC_OFFSET_TABLE_REGNUM, -32, STACK_POINTER_REGNUM);
-
- /* Profiling code.
-
- Instead of taking one argument, the counter label, as most normal
- mcounts do, _mcount appears to behave differently on the HPPA. It
- takes the return address of the caller, the address of this routine,
- and the address of the label. Also, it isn't magic, so
- argument registers have to be preserved. */
- if (profile_flag)
- {
- int pc_offset, i, arg_offset, basereg, offsetadj;
-
- pc_offset = 4 + (frame_pointer_needed
- ? (VAL_14_BITS_P (actual_fsize) ? 12 : 20)
- : (VAL_14_BITS_P (actual_fsize) ? 4 : 8));
-
- /* When the function has a frame pointer, use it as the base
- register for saving/restore registers. Else use the stack
- pointer. Adjust the offset according to the frame size if
- this function does not have a frame pointer. */
-
- basereg = frame_pointer_needed ? FRAME_POINTER_REGNUM
- : STACK_POINTER_REGNUM;
- offsetadj = frame_pointer_needed ? 0 : actual_fsize;
-
- /* Horrid hack. emit_function_prologue will modify this RTL in
- place to get the expected results. sprintf here is just to
- put something in the name. */
- sprintf(hp_profile_label_name, "LP$%04d", -1);
- hp_profile_label_rtx = gen_rtx_SYMBOL_REF (SImode, hp_profile_label_name);
- if (current_function_returns_struct)
- store_reg (STRUCT_VALUE_REGNUM, - 12 - offsetadj, basereg);
-
- for (i = 26, arg_offset = -36 - offsetadj; i >= 23; i--, arg_offset -= 4)
- if (regs_ever_live [i])
- {
- store_reg (i, arg_offset, basereg);
- /* Deal with arg_offset not fitting in 14 bits. */
- pc_offset += VAL_14_BITS_P (arg_offset) ? 4 : 8;
- }
-
- emit_move_insn (gen_rtx_REG (SImode, 26), gen_rtx_REG (SImode, 2));
- emit_move_insn (tmpreg, gen_rtx_HIGH (SImode, hp_profile_label_rtx));
- emit_move_insn (gen_rtx_REG (SImode, 24),
- gen_rtx_LO_SUM (SImode, tmpreg, hp_profile_label_rtx));
- /* %r25 is set from within the output pattern. */
- emit_insn (gen_call_profiler (GEN_INT (- pc_offset - 20)));
-
- /* Restore argument registers. */
- for (i = 26, arg_offset = -36 - offsetadj; i >= 23; i--, arg_offset -= 4)
- if (regs_ever_live [i])
- load_reg (i, arg_offset, basereg);
-
- if (current_function_returns_struct)
- load_reg (STRUCT_VALUE_REGNUM, -12 - offsetadj, basereg);
-
- }
-
- /* Normal register save.
-
- Do not save the frame pointer in the frame_pointer_needed case. It
- was done earlier. */
- if (frame_pointer_needed)
- {
- for (i = 18, offset = local_fsize; i >= 4; i--)
- if (regs_ever_live[i] && ! call_used_regs[i])
- {
- store_reg (i, offset, FRAME_POINTER_REGNUM);
- offset += 4;
- gr_saved++;
- }
- /* Account for %r3 which is saved in a special place. */
- gr_saved++;
- }
- /* No frame pointer needed. */
- else
- {
- for (i = 18, offset = local_fsize - actual_fsize; i >= 3; i--)
- if (regs_ever_live[i] && ! call_used_regs[i])
- {
- /* If merge_sp_adjust_with_store is nonzero, then we can
- optimize the first GR save. */
- if (merge_sp_adjust_with_store)
- {
- merge_sp_adjust_with_store = 0;
- emit_insn (gen_post_stwm (stack_pointer_rtx,
- gen_rtx_REG (SImode, i),
- GEN_INT (-offset)));
- }
- else
- store_reg (i, offset, STACK_POINTER_REGNUM);
- offset += 4;
- gr_saved++;
- }
-
- /* If we wanted to merge the SP adjustment with a GR save, but we never
- did any GR saves, then just emit the adjustment here. */
- if (merge_sp_adjust_with_store)
- set_reg_plus_d (STACK_POINTER_REGNUM,
- STACK_POINTER_REGNUM,
- actual_fsize);
- }
-
- /* Align pointer properly (doubleword boundary). */
- offset = (offset + 7) & ~7;
-
- /* Floating point register store. */
- if (save_fregs)
- {
- /* First get the frame or stack pointer to the start of the FP register
- save area. */
- if (frame_pointer_needed)
- set_reg_plus_d (1, FRAME_POINTER_REGNUM, offset);
- else
- set_reg_plus_d (1, STACK_POINTER_REGNUM, offset);
-
- /* Now actually save the FP registers. */
- for (i = 66; i >= 48; i -= 2)
- {
- if (regs_ever_live[i] || regs_ever_live[i + 1])
- {
- emit_move_insn (gen_rtx_MEM (DFmode,
- gen_rtx_POST_INC (DFmode, tmpreg)),
- gen_rtx_REG (DFmode, i));
- fr_saved++;
- }
- }
- }
-
- /* When generating PIC code it is necessary to save/restore the
- PIC register around each function call. We used to do this
- in the call patterns themselves, but that implementation
- made incorrect assumptions about using global variables to hold
- per-function rtl code generated in the backend.
-
- So instead, we copy the PIC register into a reserved callee saved
- register in the prologue. Then after each call we reload the PIC
- register from the callee saved register. We also reload the PIC
- register from the callee saved register in the epilogue ensure the
- PIC register is valid at function exit.
-
- This may (depending on the exact characteristics of the function)
- even be more efficient.
-
- Avoid this if the callee saved register wasn't used (these are
- leaf functions). */
- if (flag_pic && regs_ever_live[PIC_OFFSET_TABLE_REGNUM_SAVED])
- emit_move_insn (gen_rtx_REG (SImode, PIC_OFFSET_TABLE_REGNUM_SAVED),
- gen_rtx_REG (SImode, PIC_OFFSET_TABLE_REGNUM));
-}
-
-
-void
-output_function_epilogue (file, size)
- FILE *file;
- int size ATTRIBUTE_UNUSED;
-{
- rtx insn = get_last_insn ();
-
- /* hppa_expand_epilogue does the dirty work now. We just need
- to output the assembler directives which denote the end
- of a function.
-
- To make debuggers happy, emit a nop if the epilogue was completely
- eliminated due to a volatile call as the last insn in the
- current function. That way the return address (in %r2) will
- always point to a valid instruction in the current function. */
-
- /* Get the last real insn. */
- if (GET_CODE (insn) == NOTE)
- insn = prev_real_insn (insn);
-
- /* If it is a sequence, then look inside. */
- if (insn && GET_CODE (insn) == INSN && GET_CODE (PATTERN (insn)) == SEQUENCE)
- insn = XVECEXP (PATTERN (insn), 0, 0);
-
- /* If insn is a CALL_INSN, then it must be a call to a volatile
- function (otherwise there would be epilogue insns). */
- if (insn && GET_CODE (insn) == CALL_INSN)
- fputs ("\tnop\n", file);
-
- fputs ("\t.EXIT\n\t.PROCEND\n", file);
-
- /* Free up stuff we don't need anymore. */
- if (unscaled_index_insn_codes)
- free (unscaled_index_insn_codes);
- max_unscaled_index_insn_codes_uid = 0;
-}
-
-void
-hppa_expand_epilogue ()
-{
- rtx tmpreg;
- int offset,i;
- int merge_sp_adjust_with_load = 0;
-
- /* Handle out of line prologues and epilogues. */
- if (TARGET_SPACE && out_of_line_prologue_epilogue)
- {
- int saves = 0;
- rtx operands[2];
-
- /* Put the register save info into %r22. */
- for (i = 18; i >= 3; i--)
- if (regs_ever_live[i] && ! call_used_regs[i])
- {
- saves = i;
- break;
- }
-
- for (i = 66; i >= 48; i -= 2)
- if (regs_ever_live[i] || regs_ever_live[i + 1])
- {
- saves |= ((i/2 - 12 ) << 16);
- break;
- }
-
- emit_insn (gen_blockage ());
-
- /* Put the local_fisze into %r19. */
- operands[0] = gen_rtx_REG (SImode, 19);
- operands[1] = GEN_INT (local_fsize);
- emit_move_insn (operands[0], operands[1]);
-
- /* Put the stack size into %r21. */
- operands[0] = gen_rtx_REG (SImode, 21);
- operands[1] = GEN_INT (actual_fsize);
- emit_move_insn (operands[0], operands[1]);
-
- operands[0] = gen_rtx_REG (SImode, 22);
- operands[1] = GEN_INT (saves);
- emit_move_insn (operands[0], operands[1]);
-
- /* Now call the out-of-line epilogue. */
- emit_insn (gen_outline_epilogue_call ());
- return;
- }
-
- /* We will use this often. */
- tmpreg = gen_rtx_REG (SImode, 1);
-
- /* Try to restore RP early to avoid load/use interlocks when
- RP gets used in the return (bv) instruction. This appears to still
- be necessary even when we schedule the prologue and epilogue. */
- if (frame_pointer_needed
- && (regs_ever_live [2] || profile_flag))
- load_reg (2, -20, FRAME_POINTER_REGNUM);
-
- /* No frame pointer, and stack is smaller than 8k. */
- else if (! frame_pointer_needed
- && VAL_14_BITS_P (actual_fsize + 20)
- && (regs_ever_live[2] || profile_flag))
- load_reg (2, - (actual_fsize + 20), STACK_POINTER_REGNUM);
-
- /* General register restores. */
- if (frame_pointer_needed)
- {
- for (i = 18, offset = local_fsize; i >= 4; i--)
- if (regs_ever_live[i] && ! call_used_regs[i])
- {
- load_reg (i, offset, FRAME_POINTER_REGNUM);
- offset += 4;
- }
- }
- else
- {
- for (i = 18, offset = local_fsize - actual_fsize; i >= 3; i--)
- {
- if (regs_ever_live[i] && ! call_used_regs[i])
- {
- /* Only for the first load.
- merge_sp_adjust_with_load holds the register load
- with which we will merge the sp adjustment. */
- if (VAL_14_BITS_P (actual_fsize + 20)
- && local_fsize == 0
- && ! merge_sp_adjust_with_load)
- merge_sp_adjust_with_load = i;
- else
- load_reg (i, offset, STACK_POINTER_REGNUM);
- offset += 4;
- }
- }
- }
-
- /* Align pointer properly (doubleword boundary). */
- offset = (offset + 7) & ~7;
-
- /* FP register restores. */
- if (save_fregs)
- {
- /* Adjust the register to index off of. */
- if (frame_pointer_needed)
- set_reg_plus_d (1, FRAME_POINTER_REGNUM, offset);
- else
- set_reg_plus_d (1, STACK_POINTER_REGNUM, offset);
-
- /* Actually do the restores now. */
- for (i = 66; i >= 48; i -= 2)
- {
- if (regs_ever_live[i] || regs_ever_live[i + 1])
- {
- emit_move_insn (gen_rtx_REG (DFmode, i),
- gen_rtx_MEM (DFmode,
- gen_rtx_POST_INC (DFmode, tmpreg)));
- }
- }
- }
-
- /* Emit a blockage insn here to keep these insns from being moved to
- an earlier spot in the epilogue, or into the main instruction stream.
-
- This is necessary as we must not cut the stack back before all the
- restores are finished. */
- emit_insn (gen_blockage ());
- /* No frame pointer, but we have a stack greater than 8k. We restore
- %r2 very late in this case. (All other cases are restored as early
- as possible.) */
- if (! frame_pointer_needed
- && ! VAL_14_BITS_P (actual_fsize + 20)
- && (regs_ever_live[2] || profile_flag))
- {
- set_reg_plus_d (STACK_POINTER_REGNUM,
- STACK_POINTER_REGNUM,
- - actual_fsize);
-
- /* This used to try and be clever by not depending on the value in
- %r30 and instead use the value held in %r1 (so that the 2nd insn
- which sets %r30 could be put in the delay slot of the return insn).
-
- That won't work since if the stack is exactly 8k set_reg_plus_d
- doesn't set %r1, just %r30. */
- load_reg (2, - 20, STACK_POINTER_REGNUM);
- }
-
- /* Reset stack pointer (and possibly frame pointer). The stack
- pointer is initially set to fp + 64 to avoid a race condition. */
- else if (frame_pointer_needed)
- {
- set_reg_plus_d (STACK_POINTER_REGNUM, FRAME_POINTER_REGNUM, 64);
- emit_insn (gen_pre_ldwm (frame_pointer_rtx,
- stack_pointer_rtx,
- GEN_INT (-64)));
- }
- /* If we were deferring a callee register restore, do it now. */
- else if (! frame_pointer_needed && merge_sp_adjust_with_load)
- emit_insn (gen_pre_ldwm (gen_rtx_REG (SImode, merge_sp_adjust_with_load),
- stack_pointer_rtx,
- GEN_INT (- actual_fsize)));
- else if (actual_fsize != 0)
- set_reg_plus_d (STACK_POINTER_REGNUM,
- STACK_POINTER_REGNUM,
- - actual_fsize);
-}
-
-/* Fetch the return address for the frame COUNT steps up from
- the current frame, after the prologue. FRAMEADDR is the
- frame pointer of the COUNT frame.
-
- We want to ignore any export stub remnants here.
-
- The value returned is used in two different ways:
-
- 1. To find a function's caller.
-
- 2. To change the return address for a function.
-
- This function handles most instances of case 1; however, it will
- fail if there are two levels of stubs to execute on the return
- path. The only way I believe that can happen is if the return value
- needs a parameter relocation, which never happens for C code.
-
- This function handles most instances of case 2; however, it will
- fail if we did not originally have stub code on the return path
- but will need code on the new return path. This can happen if
- the caller & callee are both in the main program, but the new
- return location is in a shared library.
-
- To handle this correctly we need to set the return pointer at
- frame-20 to point to a return stub frame-24 to point to the
- location we wish to return to. */
-
-rtx
-return_addr_rtx (count, frameaddr)
- int count ATTRIBUTE_UNUSED;
- rtx frameaddr;
-{
- rtx label;
- rtx saved_rp;
- rtx ins;
-
- saved_rp = gen_reg_rtx (Pmode);
-
- /* First, we start off with the normal return address pointer from
- -20[frameaddr]. */
-
- emit_move_insn (saved_rp, plus_constant (frameaddr, -5 * UNITS_PER_WORD));
-
- /* Get pointer to the instruction stream. We have to mask out the
- privilege level from the two low order bits of the return address
- pointer here so that ins will point to the start of the first
- instruction that would have been executed if we returned. */
- ins = copy_to_reg (gen_rtx_AND (Pmode,
- copy_to_reg (gen_rtx_MEM (Pmode, saved_rp)),
- MASK_RETURN_ADDR));
- label = gen_label_rtx ();
-
- /* Check the instruction stream at the normal return address for the
- export stub:
-
- 0x4bc23fd1 | stub+8: ldw -18(sr0,sp),rp
- 0x004010a1 | stub+12: ldsid (sr0,rp),r1
- 0x00011820 | stub+16: mtsp r1,sr0
- 0xe0400002 | stub+20: be,n 0(sr0,rp)
-
- If it is an export stub, than our return address is really in
- -24[frameaddr]. */
-
- emit_cmp_insn (gen_rtx_MEM (SImode, ins),
- GEN_INT (0x4bc23fd1),
- NE, NULL_RTX, SImode, 1, 0);
- emit_jump_insn (gen_bne (label));
-
- emit_cmp_insn (gen_rtx_MEM (SImode, plus_constant (ins, 4)),
- GEN_INT (0x004010a1),
- NE, NULL_RTX, SImode, 1, 0);
- emit_jump_insn (gen_bne (label));
-
- emit_cmp_insn (gen_rtx_MEM (SImode, plus_constant (ins, 8)),
- GEN_INT (0x00011820),
- NE, NULL_RTX, SImode, 1, 0);
- emit_jump_insn (gen_bne (label));
-
- emit_cmp_insn (gen_rtx_MEM (SImode, plus_constant (ins, 12)),
- GEN_INT (0xe0400002),
- NE, NULL_RTX, SImode, 1, 0);
-
- /* If there is no export stub then just use our initial guess of
- -20[frameaddr]. */
-
- emit_jump_insn (gen_bne (label));
-
- /* Here we know that our return address pointer points to an export
- stub. We don't want to return the address of the export stub,
- but rather the return address that leads back into user code.
- That return address is stored at -24[frameaddr]. */
-
- emit_move_insn (saved_rp, plus_constant (frameaddr, -6 * UNITS_PER_WORD));
-
- emit_label (label);
- return gen_rtx_MEM (Pmode, memory_address (Pmode, saved_rp));
-}
-
-/* This is only valid once reload has completed because it depends on
- knowing exactly how much (if any) frame there is and...
-
- It's only valid if there is no frame marker to de-allocate and...
-
- It's only valid if %r2 hasn't been saved into the caller's frame
- (we're not profiling and %r2 isn't live anywhere). */
-int
-hppa_can_use_return_insn_p ()
-{
- return (reload_completed
- && (compute_frame_size (get_frame_size (), 0) ? 0 : 1)
- && ! profile_flag
- && ! regs_ever_live[2]
- && ! frame_pointer_needed);
-}
-
-void
-emit_bcond_fp (code, operand0)
- enum rtx_code code;
- rtx operand0;
-{
- emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
- gen_rtx_IF_THEN_ELSE (VOIDmode,
- gen_rtx_fmt_ee (code,
- VOIDmode,
- gen_rtx_REG (CCFPmode, 0),
- const0_rtx),
- gen_rtx_LABEL_REF (VOIDmode, operand0),
- pc_rtx)));
-
-}
-
-rtx
-gen_cmp_fp (code, operand0, operand1)
- enum rtx_code code;
- rtx operand0, operand1;
-{
- return gen_rtx_SET (VOIDmode, gen_rtx_REG (CCFPmode, 0),
- gen_rtx_fmt_ee (code, CCFPmode, operand0, operand1));
-}
-
-/* Adjust the cost of a scheduling dependency. Return the new cost of
- a dependency LINK or INSN on DEP_INSN. COST is the current cost. */
-
-int
-pa_adjust_cost (insn, link, dep_insn, cost)
- rtx insn;
- rtx link;
- rtx dep_insn;
- int cost;
-{
- enum attr_type attr_type;
-
- if (! recog_memoized (insn))
- return 0;
-
- /* CYGNUS LOCAL PA8000/law */
- /* No cost adjustments are needed for the PA8000 */
- if (pa_cpu == PROCESSOR_8000)
- return 0;
- /* END CYGNUS LOCAL */
-
- attr_type = get_attr_type (insn);
-
- if (REG_NOTE_KIND (link) == 0)
- {
- /* Data dependency; DEP_INSN writes a register that INSN reads some
- cycles later. */
-
- if (attr_type == TYPE_FPSTORE)
- {
- rtx pat = PATTERN (insn);
- rtx dep_pat = PATTERN (dep_insn);
- if (GET_CODE (pat) == PARALLEL)
- {
- /* This happens for the fstXs,mb patterns. */
- pat = XVECEXP (pat, 0, 0);
- }
- if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
- /* If this happens, we have to extend this to schedule
- optimally. Return 0 for now. */
- return 0;
-
- if (rtx_equal_p (SET_DEST (dep_pat), SET_SRC (pat)))
- {
- if (! recog_memoized (dep_insn))
- return 0;
- /* DEP_INSN is writing its result to the register
- being stored in the fpstore INSN. */
- switch (get_attr_type (dep_insn))
- {
- case TYPE_FPLOAD:
- /* This cost 3 cycles, not 2 as the md says for the
- 700 and 7100. */
- return cost + 1;
-
- case TYPE_FPALU:
- case TYPE_FPMULSGL:
- case TYPE_FPMULDBL:
- case TYPE_FPDIVSGL:
- case TYPE_FPDIVDBL:
- case TYPE_FPSQRTSGL:
- case TYPE_FPSQRTDBL:
- /* In these important cases, we save one cycle compared to
- when flop instruction feed each other. */
- return cost - 1;
-
- default:
- return cost;
- }
- }
- }
-
- /* For other data dependencies, the default cost specified in the
- md is correct. */
- return cost;
- }
- else if (REG_NOTE_KIND (link) == REG_DEP_ANTI)
- {
- /* Anti dependency; DEP_INSN reads a register that INSN writes some
- cycles later. */
-
- if (attr_type == TYPE_FPLOAD)
- {
- rtx pat = PATTERN (insn);
- rtx dep_pat = PATTERN (dep_insn);
- if (GET_CODE (pat) == PARALLEL)
- {
- /* This happens for the fldXs,mb patterns. */
- pat = XVECEXP (pat, 0, 0);
- }
- if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
- /* If this happens, we have to extend this to schedule
- optimally. Return 0 for now. */
- return 0;
-
- if (reg_mentioned_p (SET_DEST (pat), SET_SRC (dep_pat)))
- {
- if (! recog_memoized (dep_insn))
- return 0;
- switch (get_attr_type (dep_insn))
- {
- case TYPE_FPALU:
- case TYPE_FPMULSGL:
- case TYPE_FPMULDBL:
- case TYPE_FPDIVSGL:
- case TYPE_FPDIVDBL:
- case TYPE_FPSQRTSGL:
- case TYPE_FPSQRTDBL:
- /* A fpload can't be issued until one cycle before a
- preceding arithmetic operation has finished if
- the target of the fpload is any of the sources
- (or destination) of the arithmetic operation. */
- return cost - 1;
-
- default:
- return 0;
- }
- }
- }
- else if (attr_type == TYPE_FPALU)
- {
- rtx pat = PATTERN (insn);
- rtx dep_pat = PATTERN (dep_insn);
- if (GET_CODE (pat) == PARALLEL)
- {
- /* This happens for the fldXs,mb patterns. */
- pat = XVECEXP (pat, 0, 0);
- }
- if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
- /* If this happens, we have to extend this to schedule
- optimally. Return 0 for now. */
- return 0;
-
- if (reg_mentioned_p (SET_DEST (pat), SET_SRC (dep_pat)))
- {
- if (! recog_memoized (dep_insn))
- return 0;
- switch (get_attr_type (dep_insn))
- {
- case TYPE_FPDIVSGL:
- case TYPE_FPDIVDBL:
- case TYPE_FPSQRTSGL:
- case TYPE_FPSQRTDBL:
- /* An ALU flop can't be issued until two cycles before a
- preceding divide or sqrt operation has finished if
- the target of the ALU flop is any of the sources
- (or destination) of the divide or sqrt operation. */
- return cost - 2;
-
- default:
- return 0;
- }
- }
- }
-
- /* For other anti dependencies, the cost is 0. */
- return 0;
- }
- else if (REG_NOTE_KIND (link) == REG_DEP_OUTPUT)
- {
- /* Output dependency; DEP_INSN writes a register that INSN writes some
- cycles later. */
- if (attr_type == TYPE_FPLOAD)
- {
- rtx pat = PATTERN (insn);
- rtx dep_pat = PATTERN (dep_insn);
- if (GET_CODE (pat) == PARALLEL)
- {
- /* This happens for the fldXs,mb patterns. */
- pat = XVECEXP (pat, 0, 0);
- }
- if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
- /* If this happens, we have to extend this to schedule
- optimally. Return 0 for now. */
- return 0;
-
- if (reg_mentioned_p (SET_DEST (pat), SET_DEST (dep_pat)))
- {
- if (! recog_memoized (dep_insn))
- return 0;
- switch (get_attr_type (dep_insn))
- {
- case TYPE_FPALU:
- case TYPE_FPMULSGL:
- case TYPE_FPMULDBL:
- case TYPE_FPDIVSGL:
- case TYPE_FPDIVDBL:
- case TYPE_FPSQRTSGL:
- case TYPE_FPSQRTDBL:
- /* A fpload can't be issued until one cycle before a
- preceding arithmetic operation has finished if
- the target of the fpload is the destination of the
- arithmetic operation. */
- return cost - 1;
-
- default:
- return 0;
- }
- }
- }
- else if (attr_type == TYPE_FPALU)
- {
- rtx pat = PATTERN (insn);
- rtx dep_pat = PATTERN (dep_insn);
- if (GET_CODE (pat) == PARALLEL)
- {
- /* This happens for the fldXs,mb patterns. */
- pat = XVECEXP (pat, 0, 0);
- }
- if (GET_CODE (pat) != SET || GET_CODE (dep_pat) != SET)
- /* If this happens, we have to extend this to schedule
- optimally. Return 0 for now. */
- return 0;
-
- if (reg_mentioned_p (SET_DEST (pat), SET_DEST (dep_pat)))
- {
- if (! recog_memoized (dep_insn))
- return 0;
- switch (get_attr_type (dep_insn))
- {
- case TYPE_FPDIVSGL:
- case TYPE_FPDIVDBL:
- case TYPE_FPSQRTSGL:
- case TYPE_FPSQRTDBL:
- /* An ALU flop can't be issued until two cycles before a
- preceding divide or sqrt operation has finished if
- the target of the ALU flop is also the target of
- the divide or sqrt operation. */
- return cost - 2;
-
- default:
- return 0;
- }
- }
- }
-
- /* For other output dependencies, the cost is 0. */
- return 0;
- }
- else
- abort ();
-}
-
-/* Return any length adjustment needed by INSN which already has its length
- computed as LENGTH. Return zero if no adjustment is necessary.
-
- For the PA: function calls, millicode calls, and backwards short
- conditional branches with unfilled delay slots need an adjustment by +1
- (to account for the NOP which will be inserted into the instruction stream).
-
- Also compute the length of an inline block move here as it is too
- complicated to express as a length attribute in pa.md. */
-int
-pa_adjust_insn_length (insn, length)
- rtx insn;
- int length;
-{
- rtx pat = PATTERN (insn);
-
- /* Call insns which are *not* indirect and have unfilled delay slots. */
- if (GET_CODE (insn) == CALL_INSN)
- {
-
- if (GET_CODE (XVECEXP (pat, 0, 0)) == CALL
- && GET_CODE (XEXP (XEXP (XVECEXP (pat, 0, 0), 0), 0)) == SYMBOL_REF)
- return 4;
- else if (GET_CODE (XVECEXP (pat, 0, 0)) == SET
- && GET_CODE (XEXP (XEXP (XEXP (XVECEXP (pat, 0, 0), 1), 0), 0))
- == SYMBOL_REF)
- return 4;
- else
- return 0;
- }
- /* Jumps inside switch tables which have unfilled delay slots
- also need adjustment. */
- else if (GET_CODE (insn) == JUMP_INSN
- && simplejump_p (insn)
- && GET_MODE (insn) == SImode)
- return 4;
- /* Millicode insn with an unfilled delay slot. */
- else if (GET_CODE (insn) == INSN
- && GET_CODE (pat) != SEQUENCE
- && GET_CODE (pat) != USE
- && GET_CODE (pat) != CLOBBER
- && get_attr_type (insn) == TYPE_MILLI)
- return 4;
- /* Block move pattern. */
- else if (GET_CODE (insn) == INSN
- && GET_CODE (pat) == PARALLEL
- && GET_CODE (XEXP (XVECEXP (pat, 0, 0), 0)) == MEM
- && GET_CODE (XEXP (XVECEXP (pat, 0, 0), 1)) == MEM
- && GET_MODE (XEXP (XVECEXP (pat, 0, 0), 0)) == BLKmode
- && GET_MODE (XEXP (XVECEXP (pat, 0, 0), 1)) == BLKmode)
- return compute_movstrsi_length (insn) - 4;
- /* Conditional branch with an unfilled delay slot. */
- else if (GET_CODE (insn) == JUMP_INSN && ! simplejump_p (insn))
- {
- /* Adjust a short backwards conditional with an unfilled delay slot. */
- if (GET_CODE (pat) == SET
- && length == 4
- && ! forward_branch_p (insn))
- return 4;
- else if (GET_CODE (pat) == PARALLEL
- && get_attr_type (insn) == TYPE_PARALLEL_BRANCH
- && length == 4)
- return 4;
- /* Adjust dbra insn with short backwards conditional branch with
- unfilled delay slot -- only for case where counter is in a
- general register register. */
- else if (GET_CODE (pat) == PARALLEL
- && GET_CODE (XVECEXP (pat, 0, 1)) == SET
- && GET_CODE (XEXP (XVECEXP (pat, 0, 1), 0)) == REG
- && ! FP_REG_P (XEXP (XVECEXP (pat, 0, 1), 0))
- && length == 4
- && ! forward_branch_p (insn))
- return 4;
- else
- return 0;
- }
- return 0;
-}
-
-/* Print operand X (an rtx) in assembler syntax to file FILE.
- CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
- For `%' followed by punctuation, CODE is the punctuation and X is null. */
-
-void
-print_operand (file, x, code)
- FILE *file;
- rtx x;
- int code;
-{
- switch (code)
- {
- case '#':
- /* Output a 'nop' if there's nothing for the delay slot. */
- if (dbr_sequence_length () == 0)
- fputs ("\n\tnop", file);
- return;
- case '*':
- /* Output an nullification completer if there's nothing for the */
- /* delay slot or nullification is requested. */
- if (dbr_sequence_length () == 0 ||
- (final_sequence &&
- INSN_ANNULLED_BRANCH_P (XVECEXP (final_sequence, 0, 0))))
- fputs (",n", file);
- return;
- case 'R':
- /* Print out the second register name of a register pair.
- I.e., R (6) => 7. */
- fputs (reg_names[REGNO (x)+1], file);
- return;
- case 'r':
- /* A register or zero. */
- if (x == const0_rtx
- || (x == CONST0_RTX (DFmode))
- || (x == CONST0_RTX (SFmode)))
- {
- fputs ("0", file);
- return;
- }
- else
- break;
- case 'C': /* Plain (C)ondition */
- case 'X':
- switch (GET_CODE (x))
- {
- case EQ:
- fputs ("=", file); break;
- case NE:
- fputs ("<>", file); break;
- case GT:
- fputs (">", file); break;
- case GE:
- fputs (">=", file); break;
- case GEU:
- fputs (">>=", file); break;
- case GTU:
- fputs (">>", file); break;
- case LT:
- fputs ("<", file); break;
- case LE:
- fputs ("<=", file); break;
- case LEU:
- fputs ("<<=", file); break;
- case LTU:
- fputs ("<<", file); break;
- default:
- abort ();
- }
- return;
- case 'N': /* Condition, (N)egated */
- switch (GET_CODE (x))
- {
- case EQ:
- fputs ("<>", file); break;
- case NE:
- fputs ("=", file); break;
- case GT:
- fputs ("<=", file); break;
- case GE:
- fputs ("<", file); break;
- case GEU:
- fputs ("<<", file); break;
- case GTU:
- fputs ("<<=", file); break;
- case LT:
- fputs (">=", file); break;
- case LE:
- fputs (">", file); break;
- case LEU:
- fputs (">>", file); break;
- case LTU:
- fputs (">>=", file); break;
- default:
- abort ();
- }
- return;
- /* For floating point comparisons. Need special conditions to deal
- with NaNs properly. */
- case 'Y':
- switch (GET_CODE (x))
- {
- case EQ:
- fputs ("!=", file); break;
- case NE:
- fputs ("=", file); break;
- case GT:
- fputs ("<=", file); break;
- case GE:
- fputs ("<", file); break;
- case LT:
- fputs (">=", file); break;
- case LE:
- fputs (">", file); break;
- default:
- abort ();
- }
- return;
- case 'S': /* Condition, operands are (S)wapped. */
- switch (GET_CODE (x))
- {
- case EQ:
- fputs ("=", file); break;
- case NE:
- fputs ("<>", file); break;
- case GT:
- fputs ("<", file); break;
- case GE:
- fputs ("<=", file); break;
- case GEU:
- fputs ("<<=", file); break;
- case GTU:
- fputs ("<<", file); break;
- case LT:
- fputs (">", file); break;
- case LE:
- fputs (">=", file); break;
- case LEU:
- fputs (">>=", file); break;
- case LTU:
- fputs (">>", file); break;
- default:
- abort ();
- }
- return;
- case 'B': /* Condition, (B)oth swapped and negate. */
- switch (GET_CODE (x))
- {
- case EQ:
- fputs ("<>", file); break;
- case NE:
- fputs ("=", file); break;
- case GT:
- fputs (">=", file); break;
- case GE:
- fputs (">", file); break;
- case GEU:
- fputs (">>", file); break;
- case GTU:
- fputs (">>=", file); break;
- case LT:
- fputs ("<=", file); break;
- case LE:
- fputs ("<", file); break;
- case LEU:
- fputs ("<<", file); break;
- case LTU:
- fputs ("<<=", file); break;
- default:
- abort ();
- }
- return;
- case 'k':
- if (GET_CODE (x) == CONST_INT)
- {
- fprintf (file, "%d", ~INTVAL (x));
- return;
- }
- abort();
- case 'L':
- if (GET_CODE (x) == CONST_INT)
- {
- fprintf (file, "%d", 32 - (INTVAL (x) & 31));
- return;
- }
- abort();
- case 'O':
- if (GET_CODE (x) == CONST_INT && exact_log2 (INTVAL (x)) >= 0)
- {
- fprintf (file, "%d", exact_log2 (INTVAL (x)));
- return;
- }
- abort();
- case 'P':
- if (GET_CODE (x) == CONST_INT)
- {
- fprintf (file, "%d", 31 - (INTVAL (x) & 31));
- return;
- }
- abort();
- case 'I':
- if (GET_CODE (x) == CONST_INT)
- fputs ("i", file);
- return;
- case 'M':
- case 'F':
- switch (GET_CODE (XEXP (x, 0)))
- {
- case PRE_DEC:
- case PRE_INC:
- fputs ("s,mb", file);
- break;
- case POST_DEC:
- case POST_INC:
- fputs ("s,ma", file);
- break;
- case PLUS:
- if (GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT
- || GET_CODE (XEXP (XEXP (x, 0), 1)) == MULT)
- fputs ("x,s", file);
- else if (code == 'F')
- fputs ("s", file);
- break;
- default:
- if (code == 'F')
- fputs ("s", file);
- break;
- }
- return;
- case 'G':
- output_global_address (file, x, 0);
- return;
- case 'H':
- output_global_address (file, x, 1);
- return;
- case 0: /* Don't do anything special */
- break;
- case 'Z':
- {
- unsigned op[3];
- compute_zdepi_operands (INTVAL (x), op);
- fprintf (file, "%d,%d,%d", op[0], op[1], op[2]);
- return;
- }
- default:
- abort ();
- }
- if (GET_CODE (x) == REG)
- {
- fputs (reg_names [REGNO (x)], file);
- if (FP_REG_P (x) && GET_MODE_SIZE (GET_MODE (x)) <= 4 && (REGNO (x) & 1) == 0)
- fputs ("L", file);
- }
- else if (GET_CODE (x) == MEM)
- {
- int size = GET_MODE_SIZE (GET_MODE (x));
- rtx base = XEXP (XEXP (x, 0), 0);
- switch (GET_CODE (XEXP (x, 0)))
- {
- case PRE_DEC:
- case POST_DEC:
- fprintf (file, "-%d(0,%s)", size, reg_names [REGNO (base)]);
- break;
- case PRE_INC:
- case POST_INC:
- fprintf (file, "%d(0,%s)", size, reg_names [REGNO (base)]);
- break;
- default:
- if (GET_CODE (XEXP (x, 0)) == PLUS
- && GET_CODE (XEXP (XEXP (x, 0), 0)) == MULT)
- fprintf (file, "%s(0,%s)",
- reg_names [REGNO (XEXP (XEXP (XEXP (x, 0), 0), 0))],
- reg_names [REGNO (XEXP (XEXP (x, 0), 1))]);
- else if (GET_CODE (XEXP (x, 0)) == PLUS
- && GET_CODE (XEXP (XEXP (x, 0), 1)) == MULT)
- fprintf (file, "%s(0,%s)",
- reg_names [REGNO (XEXP (XEXP (XEXP (x, 0), 1), 0))],
- reg_names [REGNO (XEXP (XEXP (x, 0), 0))]);
- else
- output_address (XEXP (x, 0));
- break;
- }
- }
- else
- output_addr_const (file, x);
-}
-
-/* output a SYMBOL_REF or a CONST expression involving a SYMBOL_REF. */
-
-void
-output_global_address (file, x, round_constant)
- FILE *file;
- rtx x;
- int round_constant;
-{
-
- /* Imagine (high (const (plus ...))). */
- if (GET_CODE (x) == HIGH)
- x = XEXP (x, 0);
-
- if (GET_CODE (x) == SYMBOL_REF && read_only_operand (x))
- assemble_name (file, XSTR (x, 0));
- else if (GET_CODE (x) == SYMBOL_REF && !flag_pic)
- {
- assemble_name (file, XSTR (x, 0));
- fputs ("-$global$", file);
- }
- else if (GET_CODE (x) == CONST)
- {
- char *sep = "";
- int offset = 0; /* assembler wants -$global$ at end */
- rtx base = NULL_RTX;
-
- if (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF)
- {
- base = XEXP (XEXP (x, 0), 0);
- output_addr_const (file, base);
- }
- else if (GET_CODE (XEXP (XEXP (x, 0), 0)) == CONST_INT)
- offset = INTVAL (XEXP (XEXP (x, 0), 0));
- else abort ();
-
- if (GET_CODE (XEXP (XEXP (x, 0), 1)) == SYMBOL_REF)
- {
- base = XEXP (XEXP (x, 0), 1);
- output_addr_const (file, base);
- }
- else if (GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
- offset = INTVAL (XEXP (XEXP (x, 0),1));
- else abort ();
-
- /* How bogus. The compiler is apparently responsible for
- rounding the constant if it uses an LR field selector.
-
- The linker and/or assembler seem a better place since
- they have to do this kind of thing already.
-
- If we fail to do this, HP's optimizing linker may eliminate
- an addil, but not update the ldw/stw/ldo instruction that
- uses the result of the addil. */
- if (round_constant)
- offset = ((offset + 0x1000) & ~0x1fff);
-
- if (GET_CODE (XEXP (x, 0)) == PLUS)
- {
- if (offset < 0)
- {
- offset = -offset;
- sep = "-";
- }
- else
- sep = "+";
- }
- else if (GET_CODE (XEXP (x, 0)) == MINUS
- && (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF))
- sep = "-";
- else abort ();
-
- if (!read_only_operand (base) && !flag_pic)
- fputs ("-$global$", file);
- if (offset)
- fprintf (file,"%s%d", sep, offset);
- }
- else
- output_addr_const (file, x);
-}
-
-void
-output_deferred_plabels (file)
- FILE *file;
-{
- int i;
- /* If we have deferred plabels, then we need to switch into the data
- section and align it to a 4 byte boundary before we output the
- deferred plabels. */
- if (n_deferred_plabels)
- {
- data_section ();
- ASM_OUTPUT_ALIGN (file, 2);
- }
-
- /* Now output the deferred plabels. */
- for (i = 0; i < n_deferred_plabels; i++)
- {
- ASM_OUTPUT_INTERNAL_LABEL (file, "L", CODE_LABEL_NUMBER (deferred_plabels[i].internal_label));
- assemble_integer (gen_rtx_SYMBOL_REF (VOIDmode,
- deferred_plabels[i].name), 4, 1);
- }
-}
-
-/* HP's millicode routines mean something special to the assembler.
- Keep track of which ones we have used. */
-
-enum millicodes { remI, remU, divI, divU, mulI, mulU, end1000 };
-static char imported[(int)end1000];
-static char *milli_names[] = {"remI", "remU", "divI", "divU", "mulI", "mulU"};
-static char import_string[] = ".IMPORT $$....,MILLICODE";
-#define MILLI_START 10
-
-static void
-import_milli (code)
- enum millicodes code;
-{
- char str[sizeof (import_string)];
-
- if (!imported[(int)code])
- {
- imported[(int)code] = 1;
- strcpy (str, import_string);
- strncpy (str + MILLI_START, milli_names[(int)code], 4);
- output_asm_insn (str, 0);
- }
-}
-
-/* The register constraints have put the operands and return value in
- the proper registers. */
-
-char *
-output_mul_insn (unsignedp, insn)
- int unsignedp ATTRIBUTE_UNUSED;
- rtx insn;
-{
- import_milli (mulI);
- return output_millicode_call (insn, gen_rtx_SYMBOL_REF (SImode, "$$mulI"));
-}
-
-/* Emit the rtl for doing a division by a constant. */
-
-/* Do magic division millicodes exist for this value? */
-static int magic_milli[]= {0, 0, 0, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0,
- 1, 1};
-
-/* We'll use an array to keep track of the magic millicodes and
- whether or not we've used them already. [n][0] is signed, [n][1] is
- unsigned. */
-
-static int div_milli[16][2];
-
-int
-div_operand (op, mode)
- rtx op;
- enum machine_mode mode;
-{
- return (mode == SImode
- && ((GET_CODE (op) == REG && REGNO (op) == 25)
- || (GET_CODE (op) == CONST_INT && INTVAL (op) > 0
- && INTVAL (op) < 16 && magic_milli[INTVAL (op)])));
-}
-
-int
-emit_hpdiv_const (operands, unsignedp)
- rtx *operands;
- int unsignedp;
-{
- if (GET_CODE (operands[2]) == CONST_INT
- && INTVAL (operands[2]) > 0
- && INTVAL (operands[2]) < 16
- && magic_milli[INTVAL (operands[2])])
- {
- emit_move_insn (gen_rtx_REG (SImode, 26), operands[1]);
- emit
- (gen_rtx
- (PARALLEL, VOIDmode,
- gen_rtvec (5, gen_rtx_SET (VOIDmode, gen_rtx_REG (SImode, 29),
- gen_rtx_fmt_ee (unsignedp ? UDIV : DIV,
- SImode,
- gen_rtx_REG (SImode, 26),
- operands[2])),
- gen_rtx_CLOBBER (VOIDmode, operands[3]),
- gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 26)),
- gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 25)),
- gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (SImode, 31)))));
- emit_move_insn (operands[0], gen_rtx_REG (SImode, 29));
- return 1;
- }
- return 0;
-}
-
-char *
-output_div_insn (operands, unsignedp, insn)
- rtx *operands;
- int unsignedp;
- rtx insn;
-{
- int divisor;
-
- /* If the divisor is a constant, try to use one of the special
- opcodes .*/
- if (GET_CODE (operands[0]) == CONST_INT)
- {
- static char buf[100];
- divisor = INTVAL (operands[0]);
- if (!div_milli[divisor][unsignedp])
- {
- div_milli[divisor][unsignedp] = 1;
- if (unsignedp)
- output_asm_insn (".IMPORT $$divU_%0,MILLICODE", operands);
- else
- output_asm_insn (".IMPORT $$divI_%0,MILLICODE", operands);
- }
- if (unsignedp)
- {
- sprintf (buf, "$$divU_%d", INTVAL (operands[0]));
- return output_millicode_call (insn,
- gen_rtx_SYMBOL_REF (SImode, buf));
- }
- else
- {
- sprintf (buf, "$$divI_%d", INTVAL (operands[0]));
- return output_millicode_call (insn,
- gen_rtx_SYMBOL_REF (SImode, buf));
- }
- }
- /* Divisor isn't a special constant. */
- else
- {
- if (unsignedp)
- {
- import_milli (divU);
- return output_millicode_call (insn,
- gen_rtx_SYMBOL_REF (SImode, "$$divU"));
- }
- else
- {
- import_milli (divI);
- return output_millicode_call (insn,
- gen_rtx_SYMBOL_REF (SImode, "$$divI"));
- }
- }
-}
-
-/* Output a $$rem millicode to do mod. */
-
-char *
-output_mod_insn (unsignedp, insn)
- int unsignedp;
- rtx insn;
-{
- if (unsignedp)
- {
- import_milli (remU);
- return output_millicode_call (insn,
- gen_rtx_SYMBOL_REF (SImode, "$$remU"));
- }
- else
- {
- import_milli (remI);
- return output_millicode_call (insn,
- gen_rtx_SYMBOL_REF (SImode, "$$remI"));
- }
-}
-
-void
-output_arg_descriptor (call_insn)
- rtx call_insn;
-{
- char *arg_regs[4];
- enum machine_mode arg_mode;
- rtx link;
- int i, output_flag = 0;
- int regno;
-
- for (i = 0; i < 4; i++)
- arg_regs[i] = 0;
-
- /* Specify explicitly that no argument relocations should take place
- if using the portable runtime calling conventions. */
- if (TARGET_PORTABLE_RUNTIME)
- {
- fputs ("\t.CALL ARGW0=NO,ARGW1=NO,ARGW2=NO,ARGW3=NO,RETVAL=NO\n",
- asm_out_file);
- return;
- }
-
- if (GET_CODE (call_insn) != CALL_INSN)
- abort ();
- for (link = CALL_INSN_FUNCTION_USAGE (call_insn); link; link = XEXP (link, 1))
- {
- rtx use = XEXP (link, 0);
-
- if (! (GET_CODE (use) == USE
- && GET_CODE (XEXP (use, 0)) == REG
- && FUNCTION_ARG_REGNO_P (REGNO (XEXP (use, 0)))))
- continue;
-
- arg_mode = GET_MODE (XEXP (use, 0));
- regno = REGNO (XEXP (use, 0));
- if (regno >= 23 && regno <= 26)
- {
- arg_regs[26 - regno] = "GR";
- if (arg_mode == DImode)
- arg_regs[25 - regno] = "GR";
- }
- else if (regno >= 32 && regno <= 39)
- {
- if (arg_mode == SFmode)
- arg_regs[(regno - 32) / 2] = "FR";
- else
- {
-#ifndef HP_FP_ARG_DESCRIPTOR_REVERSED
- arg_regs[(regno - 34) / 2] = "FR";
- arg_regs[(regno - 34) / 2 + 1] = "FU";
-#else
- arg_regs[(regno - 34) / 2] = "FU";
- arg_regs[(regno - 34) / 2 + 1] = "FR";
-#endif
- }
- }
- }
- fputs ("\t.CALL ", asm_out_file);
- for (i = 0; i < 4; i++)
- {
- if (arg_regs[i])
- {
- if (output_flag++)
- fputc (',', asm_out_file);
- fprintf (asm_out_file, "ARGW%d=%s", i, arg_regs[i]);
- }
- }
- fputc ('\n', asm_out_file);
-}
-
-/* Return the class of any secondary reload register that is needed to
- move IN into a register in class CLASS using mode MODE.
-
- Profiling has showed this routine and its descendants account for
- a significant amount of compile time (~7%). So it has been
- optimized to reduce redundant computations and eliminate useless
- function calls.
-
- It might be worthwhile to try and make this a leaf function too. */
-
-enum reg_class
-secondary_reload_class (class, mode, in)
- enum reg_class class;
- enum machine_mode mode;
- rtx in;
-{
- int regno, is_symbolic;
-
- /* Trying to load a constant into a FP register during PIC code
- generation will require %r1 as a scratch register. */
- if (flag_pic == 2
- && GET_MODE_CLASS (mode) == MODE_INT
- && FP_REG_CLASS_P (class)
- && (GET_CODE (in) == CONST_INT || GET_CODE (in) == CONST_DOUBLE))
- return R1_REGS;
-
- /* Profiling showed the PA port spends about 1.3% of its compilation
- time in true_regnum from calls inside secondary_reload_class. */
-
- if (GET_CODE (in) == REG)
- {
- regno = REGNO (in);
- if (regno >= FIRST_PSEUDO_REGISTER)
- regno = true_regnum (in);
- }
- else if (GET_CODE (in) == SUBREG)
- regno = true_regnum (in);
- else
- regno = -1;
-
- /* If we have something like (mem (mem (...)), we can safely assume the
- inner MEM will end up in a general register after reloading, so there's
- no need for a secondary reload. */
- if (GET_CODE (in) == MEM
- && GET_CODE (XEXP (in, 0)) == MEM)
- return NO_REGS;
-
- /* Handle out of range displacement for integer mode loads/stores of
- FP registers. */
- if (((regno >= FIRST_PSEUDO_REGISTER || regno == -1)
- && GET_MODE_CLASS (mode) == MODE_INT
- && FP_REG_CLASS_P (class))
- || (class == SHIFT_REGS && (regno <= 0 || regno >= 32)))
- return GENERAL_REGS;
-
- if (GET_CODE (in) == HIGH)
- in = XEXP (in, 0);
-
- /* Profiling has showed GCC spends about 2.6% of its compilation
- time in symbolic_operand from calls inside secondary_reload_class.
-
- We use an inline copy and only compute its return value once to avoid
- useless work. */
- switch (GET_CODE (in))
- {
- rtx tmp;
-
- case SYMBOL_REF:
- case LABEL_REF:
- is_symbolic = 1;
- break;
- case CONST:
- tmp = XEXP (in, 0);
- is_symbolic = ((GET_CODE (XEXP (tmp, 0)) == SYMBOL_REF
- || GET_CODE (XEXP (tmp, 0)) == LABEL_REF)
- && GET_CODE (XEXP (tmp, 1)) == CONST_INT);
- break;
-
- default:
- is_symbolic = 0;
- break;
- }
-
- if (!flag_pic
- && is_symbolic
- && read_only_operand (in))
- return NO_REGS;
-
- if (class != R1_REGS && is_symbolic)
- return R1_REGS;
-
- return NO_REGS;
-}
-
-enum direction
-function_arg_padding (mode, type)
- enum machine_mode mode;
- tree type;
-{
- int size;
-
- if (mode == BLKmode)
- {
- if (type && TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST)
- size = int_size_in_bytes (type) * BITS_PER_UNIT;
- else
- return upward; /* Don't know if this is right, but */
- /* same as old definition. */
- }
- else
- size = GET_MODE_BITSIZE (mode);
- if (size < PARM_BOUNDARY)
- return downward;
- else if (size % PARM_BOUNDARY)
- return upward;
- else
- return none;
-}
-
-
-/* Do what is necessary for `va_start'. The argument is ignored;
- We look at the current function to determine if stdargs or varargs
- is used and fill in an initial va_list. A pointer to this constructor
- is returned. */
-
-struct rtx_def *
-hppa_builtin_saveregs (arglist)
- tree arglist ATTRIBUTE_UNUSED;
-{
- rtx offset, dest;
- tree fntype = TREE_TYPE (current_function_decl);
- int argadj = ((!(TYPE_ARG_TYPES (fntype) != 0
- && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (fntype)))
- != void_type_node)))
- ? UNITS_PER_WORD : 0);
-
- if (argadj)
- offset = plus_constant (current_function_arg_offset_rtx, argadj);
- else
- offset = current_function_arg_offset_rtx;
-
- /* Store general registers on the stack. */
- dest = gen_rtx_MEM (BLKmode,
- plus_constant (current_function_internal_arg_pointer,
- -16));
- move_block_from_reg (23, dest, 4, 4 * UNITS_PER_WORD);
-
- /* move_block_from_reg will emit code to store the argument registers
- individually as scalar stores.
-
- However, other insns may later load from the same addresses for
- a structure load (passing a struct to a varargs routine).
-
- The alias code assumes that such aliasing can never happen, so we
- have to keep memory referencing insns from moving up beyond the
- last argument register store. So we emit a blockage insn here. */
- emit_insn (gen_blockage ());
-
- if (current_function_check_memory_usage)
- emit_library_call (chkr_set_right_libfunc, 1, VOIDmode, 3,
- dest, ptr_mode,
- GEN_INT (4 * UNITS_PER_WORD), TYPE_MODE (sizetype),
- GEN_INT (MEMORY_USE_RW),
- TYPE_MODE (integer_type_node));
-
- return copy_to_reg (expand_binop (Pmode, add_optab,
- current_function_internal_arg_pointer,
- offset, 0, 0, OPTAB_LIB_WIDEN));
-}
-
-/* This routine handles all the normal conditional branch sequences we
- might need to generate. It handles compare immediate vs compare
- register, nullification of delay slots, varying length branches,
- negated branches, and all combinations of the above. It returns the
- output appropriate to emit the branch corresponding to all given
- parameters. */
-
-char *
-output_cbranch (operands, nullify, length, negated, insn)
- rtx *operands;
- int nullify, length, negated;
- rtx insn;
-{
- static char buf[100];
- int useskip = 0;
-
- /* A conditional branch to the following instruction (eg the delay slot) is
- asking for a disaster. This can happen when not optimizing.
-
- In such cases it is safe to emit nothing. */
-
- if (next_active_insn (JUMP_LABEL (insn)) == next_active_insn (insn))
- return "";
-
- /* If this is a long branch with its delay slot unfilled, set `nullify'
- as it can nullify the delay slot and save a nop. */
- if (length == 8 && dbr_sequence_length () == 0)
- nullify = 1;
-
- /* If this is a short forward conditional branch which did not get
- its delay slot filled, the delay slot can still be nullified. */
- if (! nullify && length == 4 && dbr_sequence_length () == 0)
- nullify = forward_branch_p (insn);
-
- /* A forward branch over a single nullified insn can be done with a
- comclr instruction. This avoids a single cycle penalty due to
- mis-predicted branch if we fall through (branch not taken). */
- if (length == 4
- && next_real_insn (insn) != 0
- && get_attr_length (next_real_insn (insn)) == 4
- && JUMP_LABEL (insn) == next_nonnote_insn (next_real_insn (insn))
- && nullify)
- useskip = 1;
-
- switch (length)
- {
- /* All short conditional branches except backwards with an unfilled
- delay slot. */
- case 4:
- if (useskip)
- strcpy (buf, "com%I2clr,");
- else
- strcpy (buf, "com%I2b,");
- if (negated)
- strcat (buf, "%B3");
- else
- strcat (buf, "%S3");
- if (useskip)
- strcat (buf, " %2,%r1,0");
- else if (nullify)
- strcat (buf, ",n %2,%r1,%0");
- else
- strcat (buf, " %2,%r1,%0");
- break;
-
- /* All long conditionals. Note an short backward branch with an
- unfilled delay slot is treated just like a long backward branch
- with an unfilled delay slot. */
- case 8:
- /* Handle weird backwards branch with a filled delay slot
- with is nullified. */
- if (dbr_sequence_length () != 0
- && ! forward_branch_p (insn)
- && nullify)
- {
- strcpy (buf, "com%I2b,");
- if (negated)
- strcat (buf, "%S3");
- else
- strcat (buf, "%B3");
- strcat (buf, ",n %2,%r1,.+12\n\tbl %0,0");
- }
- /* Handle short backwards branch with an unfilled delay slot.
- Using a comb;nop rather than comiclr;bl saves 1 cycle for both
- taken and untaken branches. */
- else if (dbr_sequence_length () == 0
- && ! forward_branch_p (insn)
- && insn_addresses
- && VAL_14_BITS_P (insn_addresses[INSN_UID (JUMP_LABEL (insn))]
- - insn_addresses[INSN_UID (insn)] - 8))
- {
- strcpy (buf, "com%I2b,");
- if (negated)
- strcat (buf, "%B3 %2,%r1,%0%#");
- else
- strcat (buf, "%S3 %2,%r1,%0%#");
- }
- else
- {
- strcpy (buf, "com%I2clr,");
- if (negated)
- strcat (buf, "%S3");
- else
- strcat (buf, "%B3");
- if (nullify)
- strcat (buf, " %2,%r1,0\n\tbl,n %0,0");
- else
- strcat (buf, " %2,%r1,0\n\tbl %0,0");
- }
- break;
-
- case 20:
- /* Very long branch. Right now we only handle these when not
- optimizing. See "jump" pattern in pa.md for details. */
- if (optimize)
- abort ();
-
- /* Create a reversed conditional branch which branches around
- the following insns. */
- if (negated)
- strcpy (buf, "com%I2b,%S3,n %2,%r1,.+20");
- else
- strcpy (buf, "com%I2b,%B3,n %2,%r1,.+20");
- output_asm_insn (buf, operands);
-
- /* Output an insn to save %r1. */
- output_asm_insn ("stw %%r1,-16(%%r30)", operands);
-
- /* Now output a very long branch to the original target. */
- output_asm_insn ("ldil L'%l0,%%r1\n\tbe R'%l0(%%sr4,%%r1)", operands);
-
- /* Now restore the value of %r1 in the delay slot. We're not
- optimizing so we know nothing else can be in the delay slot. */
- return "ldw -16(%%r30),%%r1";
-
- case 28:
- /* Very long branch when generating PIC code. Right now we only
- handle these when not optimizing. See "jump" pattern in pa.md
- for details. */
- if (optimize)
- abort ();
-
- /* Create a reversed conditional branch which branches around
- the following insns. */
- if (negated)
- strcpy (buf, "com%I2b,%S3,n %2,%r1,.+28");
- else
- strcpy (buf, "com%I2b,%B3,n %2,%r1,.+28");
- output_asm_insn (buf, operands);
-
- /* Output an insn to save %r1. */
- output_asm_insn ("stw %%r1,-16(%%r30)", operands);
-
- /* Now output a very long PIC branch to the original target. */
- {
- rtx xoperands[5];
-
- xoperands[0] = operands[0];
- xoperands[1] = operands[1];
- xoperands[2] = operands[2];
- xoperands[3] = operands[3];
- xoperands[4] = gen_label_rtx ();
-
- output_asm_insn ("bl .+8,%%r1\n\taddil L'%l0-%l4,%%r1", xoperands);
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
- CODE_LABEL_NUMBER (xoperands[4]));
- output_asm_insn ("ldo R'%l0-%l4(%%r1),%%r1\n\tbv 0(%%r1)", xoperands);
- }
-
- /* Now restore the value of %r1 in the delay slot. We're not
- optimizing so we know nothing else can be in the delay slot. */
- return "ldw -16(%%r30),%%r1";
-
- default:
- abort();
- }
- return buf;
-}
-
-/* This routine handles all the branch-on-bit conditional branch sequences we
- might need to generate. It handles nullification of delay slots,
- varying length branches, negated branches and all combinations of the
- above. it returns the appropriate output template to emit the branch. */
-
-char *
-output_bb (operands, nullify, length, negated, insn, which)
- rtx *operands ATTRIBUTE_UNUSED;
- int nullify, length, negated;
- rtx insn;
- int which;
-{
- static char buf[100];
- int useskip = 0;
-
- /* A conditional branch to the following instruction (eg the delay slot) is
- asking for a disaster. I do not think this can happen as this pattern
- is only used when optimizing; jump optimization should eliminate the
- jump. But be prepared just in case. */
-
- if (next_active_insn (JUMP_LABEL (insn)) == next_active_insn (insn))
- return "";
-
- /* If this is a long branch with its delay slot unfilled, set `nullify'
- as it can nullify the delay slot and save a nop. */
- if (length == 8 && dbr_sequence_length () == 0)
- nullify = 1;
-
- /* If this is a short forward conditional branch which did not get
- its delay slot filled, the delay slot can still be nullified. */
- if (! nullify && length == 4 && dbr_sequence_length () == 0)
- nullify = forward_branch_p (insn);
-
- /* A forward branch over a single nullified insn can be done with a
- extrs instruction. This avoids a single cycle penalty due to
- mis-predicted branch if we fall through (branch not taken). */
-
- if (length == 4
- && next_real_insn (insn) != 0
- && get_attr_length (next_real_insn (insn)) == 4
- && JUMP_LABEL (insn) == next_nonnote_insn (next_real_insn (insn))
- && nullify)
- useskip = 1;
-
- switch (length)
- {
-
- /* All short conditional branches except backwards with an unfilled
- delay slot. */
- case 4:
- if (useskip)
- strcpy (buf, "extrs,");
- else
- strcpy (buf, "bb,");
- if ((which == 0 && negated)
- || (which == 1 && ! negated))
- strcat (buf, ">=");
- else
- strcat (buf, "<");
- if (useskip)
- strcat (buf, " %0,%1,1,0");
- else if (nullify && negated)
- strcat (buf, ",n %0,%1,%3");
- else if (nullify && ! negated)
- strcat (buf, ",n %0,%1,%2");
- else if (! nullify && negated)
- strcat (buf, "%0,%1,%3");
- else if (! nullify && ! negated)
- strcat (buf, " %0,%1,%2");
- break;
-
- /* All long conditionals. Note an short backward branch with an
- unfilled delay slot is treated just like a long backward branch
- with an unfilled delay slot. */
- case 8:
- /* Handle weird backwards branch with a filled delay slot
- with is nullified. */
- if (dbr_sequence_length () != 0
- && ! forward_branch_p (insn)
- && nullify)
- {
- strcpy (buf, "bb,");
- if ((which == 0 && negated)
- || (which == 1 && ! negated))
- strcat (buf, "<");
- else
- strcat (buf, ">=");
- if (negated)
- strcat (buf, ",n %0,%1,.+12\n\tbl %3,0");
- else
- strcat (buf, ",n %0,%1,.+12\n\tbl %2,0");
- }
- /* Handle short backwards branch with an unfilled delay slot.
- Using a bb;nop rather than extrs;bl saves 1 cycle for both
- taken and untaken branches. */
- else if (dbr_sequence_length () == 0
- && ! forward_branch_p (insn)
- && insn_addresses
- && VAL_14_BITS_P (insn_addresses[INSN_UID (JUMP_LABEL (insn))]
- - insn_addresses[INSN_UID (insn)] - 8))
- {
- strcpy (buf, "bb,");
- if ((which == 0 && negated)
- || (which == 1 && ! negated))
- strcat (buf, ">=");
- else
- strcat (buf, "<");
- if (negated)
- strcat (buf, " %0,%1,%3%#");
- else
- strcat (buf, " %0,%1,%2%#");
- }
- else
- {
- strcpy (buf, "extrs,");
- if ((which == 0 && negated)
- || (which == 1 && ! negated))
- strcat (buf, "<");
- else
- strcat (buf, ">=");
- if (nullify && negated)
- strcat (buf, " %0,%1,1,0\n\tbl,n %3,0");
- else if (nullify && ! negated)
- strcat (buf, " %0,%1,1,0\n\tbl,n %2,0");
- else if (negated)
- strcat (buf, " %0,%1,1,0\n\tbl %3,0");
- else
- strcat (buf, " %0,%1,1,0\n\tbl %2,0");
- }
- break;
-
- default:
- abort();
- }
- return buf;
-}
-
-/* This routine handles all the branch-on-variable-bit conditional branch
- sequences we might need to generate. It handles nullification of delay
- slots, varying length branches, negated branches and all combinations
- of the above. it returns the appropriate output template to emit the
- branch. */
-
-char *
-output_bvb (operands, nullify, length, negated, insn, which)
- rtx *operands ATTRIBUTE_UNUSED;
- int nullify, length, negated;
- rtx insn;
- int which;
-{
- static char buf[100];
- int useskip = 0;
-
- /* A conditional branch to the following instruction (eg the delay slot) is
- asking for a disaster. I do not think this can happen as this pattern
- is only used when optimizing; jump optimization should eliminate the
- jump. But be prepared just in case. */
-
- if (next_active_insn (JUMP_LABEL (insn)) == next_active_insn (insn))
- return "";
-
- /* If this is a long branch with its delay slot unfilled, set `nullify'
- as it can nullify the delay slot and save a nop. */
- if (length == 8 && dbr_sequence_length () == 0)
- nullify = 1;
-
- /* If this is a short forward conditional branch which did not get
- its delay slot filled, the delay slot can still be nullified. */
- if (! nullify && length == 4 && dbr_sequence_length () == 0)
- nullify = forward_branch_p (insn);
-
- /* A forward branch over a single nullified insn can be done with a
- extrs instruction. This avoids a single cycle penalty due to
- mis-predicted branch if we fall through (branch not taken). */
-
- if (length == 4
- && next_real_insn (insn) != 0
- && get_attr_length (next_real_insn (insn)) == 4
- && JUMP_LABEL (insn) == next_nonnote_insn (next_real_insn (insn))
- && nullify)
- useskip = 1;
-
- switch (length)
- {
-
- /* All short conditional branches except backwards with an unfilled
- delay slot. */
- case 4:
- if (useskip)
- strcpy (buf, "vextrs,");
- else
- strcpy (buf, "bvb,");
- if ((which == 0 && negated)
- || (which == 1 && ! negated))
- strcat (buf, ">=");
- else
- strcat (buf, "<");
- if (useskip)
- strcat (buf, " %0,1,0");
- else if (nullify && negated)
- strcat (buf, ",n %0,%3");
- else if (nullify && ! negated)
- strcat (buf, ",n %0,%2");
- else if (! nullify && negated)
- strcat (buf, "%0,%3");
- else if (! nullify && ! negated)
- strcat (buf, " %0,%2");
- break;
-
- /* All long conditionals. Note an short backward branch with an
- unfilled delay slot is treated just like a long backward branch
- with an unfilled delay slot. */
- case 8:
- /* Handle weird backwards branch with a filled delay slot
- with is nullified. */
- if (dbr_sequence_length () != 0
- && ! forward_branch_p (insn)
- && nullify)
- {
- strcpy (buf, "bvb,");
- if ((which == 0 && negated)
- || (which == 1 && ! negated))
- strcat (buf, "<");
- else
- strcat (buf, ">=");
- if (negated)
- strcat (buf, ",n %0,.+12\n\tbl %3,0");
- else
- strcat (buf, ",n %0,.+12\n\tbl %2,0");
- }
- /* Handle short backwards branch with an unfilled delay slot.
- Using a bb;nop rather than extrs;bl saves 1 cycle for both
- taken and untaken branches. */
- else if (dbr_sequence_length () == 0
- && ! forward_branch_p (insn)
- && insn_addresses
- && VAL_14_BITS_P (insn_addresses[INSN_UID (JUMP_LABEL (insn))]
- - insn_addresses[INSN_UID (insn)] - 8))
- {
- strcpy (buf, "bvb,");
- if ((which == 0 && negated)
- || (which == 1 && ! negated))
- strcat (buf, ">=");
- else
- strcat (buf, "<");
- if (negated)
- strcat (buf, " %0,%3%#");
- else
- strcat (buf, " %0,%2%#");
- }
- else
- {
- strcpy (buf, "vextrs,");
- if ((which == 0 && negated)
- || (which == 1 && ! negated))
- strcat (buf, "<");
- else
- strcat (buf, ">=");
- if (nullify && negated)
- strcat (buf, " %0,1,0\n\tbl,n %3,0");
- else if (nullify && ! negated)
- strcat (buf, " %0,1,0\n\tbl,n %2,0");
- else if (negated)
- strcat (buf, " %0,1,0\n\tbl %3,0");
- else
- strcat (buf, " %0,1,0\n\tbl %2,0");
- }
- break;
-
- default:
- abort();
- }
- return buf;
-}
-
-/* Return the output template for emitting a dbra type insn.
-
- Note it may perform some output operations on its own before
- returning the final output string. */
-char *
-output_dbra (operands, insn, which_alternative)
- rtx *operands;
- rtx insn;
- int which_alternative;
-{
-
- /* A conditional branch to the following instruction (eg the delay slot) is
- asking for a disaster. Be prepared! */
-
- if (next_active_insn (JUMP_LABEL (insn)) == next_active_insn (insn))
- {
- if (which_alternative == 0)
- return "ldo %1(%0),%0";
- else if (which_alternative == 1)
- {
- output_asm_insn ("fstws %0,-16(0,%%r30)",operands);
- output_asm_insn ("ldw -16(0,%%r30),%4",operands);
- output_asm_insn ("ldo %1(%4),%4\n\tstw %4,-16(0,%%r30)", operands);
- return "fldws -16(0,%%r30),%0";
- }
- else
- {
- output_asm_insn ("ldw %0,%4", operands);
- return "ldo %1(%4),%4\n\tstw %4,%0";
- }
- }
-
- if (which_alternative == 0)
- {
- int nullify = INSN_ANNULLED_BRANCH_P (insn);
- int length = get_attr_length (insn);
-
- /* If this is a long branch with its delay slot unfilled, set `nullify'
- as it can nullify the delay slot and save a nop. */
- if (length == 8 && dbr_sequence_length () == 0)
- nullify = 1;
-
- /* If this is a short forward conditional branch which did not get
- its delay slot filled, the delay slot can still be nullified. */
- if (! nullify && length == 4 && dbr_sequence_length () == 0)
- nullify = forward_branch_p (insn);
-
- /* Handle short versions first. */
- if (length == 4 && nullify)
- return "addib,%C2,n %1,%0,%3";
- else if (length == 4 && ! nullify)
- return "addib,%C2 %1,%0,%3";
- else if (length == 8)
- {
- /* Handle weird backwards branch with a fulled delay slot
- which is nullified. */
- if (dbr_sequence_length () != 0
- && ! forward_branch_p (insn)
- && nullify)
- return "addib,%N2,n %1,%0,.+12\n\tbl %3,0";
- /* Handle short backwards branch with an unfilled delay slot.
- Using a addb;nop rather than addi;bl saves 1 cycle for both
- taken and untaken branches. */
- else if (dbr_sequence_length () == 0
- && ! forward_branch_p (insn)
- && insn_addresses
- && VAL_14_BITS_P (insn_addresses[INSN_UID (JUMP_LABEL (insn))]
- - insn_addresses[INSN_UID (insn)] - 8))
- return "addib,%C2 %1,%0,%3%#";
-
- /* Handle normal cases. */
- if (nullify)
- return "addi,%N2 %1,%0,%0\n\tbl,n %3,0";
- else
- return "addi,%N2 %1,%0,%0\n\tbl %3,0";
- }
- else
- abort();
- }
- /* Deal with gross reload from FP register case. */
- else if (which_alternative == 1)
- {
- /* Move loop counter from FP register to MEM then into a GR,
- increment the GR, store the GR into MEM, and finally reload
- the FP register from MEM from within the branch's delay slot. */
- output_asm_insn ("fstws %0,-16(0,%%r30)\n\tldw -16(0,%%r30),%4",operands);
- output_asm_insn ("ldo %1(%4),%4\n\tstw %4,-16(0,%%r30)", operands);
- if (get_attr_length (insn) == 24)
- return "comb,%S2 0,%4,%3\n\tfldws -16(0,%%r30),%0";
- else
- return "comclr,%B2 0,%4,0\n\tbl %3,0\n\tfldws -16(0,%%r30),%0";
- }
- /* Deal with gross reload from memory case. */
- else
- {
- /* Reload loop counter from memory, the store back to memory
- happens in the branch's delay slot. */
- output_asm_insn ("ldw %0,%4", operands);
- if (get_attr_length (insn) == 12)
- return "addib,%C2 %1,%4,%3\n\tstw %4,%0";
- else
- return "addi,%N2 %1,%4,%4\n\tbl %3,0\n\tstw %4,%0";
- }
-}
-
-/* Return the output template for emitting a dbra type insn.
-
- Note it may perform some output operations on its own before
- returning the final output string. */
-char *
-output_movb (operands, insn, which_alternative, reverse_comparison)
- rtx *operands;
- rtx insn;
- int which_alternative;
- int reverse_comparison;
-{
-
- /* A conditional branch to the following instruction (eg the delay slot) is
- asking for a disaster. Be prepared! */
-
- if (next_active_insn (JUMP_LABEL (insn)) == next_active_insn (insn))
- {
- if (which_alternative == 0)
- return "copy %1,%0";
- else if (which_alternative == 1)
- {
- output_asm_insn ("stw %1,-16(0,%%r30)",operands);
- return "fldws -16(0,%%r30),%0";
- }
- else if (which_alternative == 2)
- return "stw %1,%0";
- else
- return "mtsar %r1";
- }
-
- /* Support the second variant. */
- if (reverse_comparison)
- PUT_CODE (operands[2], reverse_condition (GET_CODE (operands[2])));
-
- if (which_alternative == 0)
- {
- int nullify = INSN_ANNULLED_BRANCH_P (insn);
- int length = get_attr_length (insn);
-
- /* If this is a long branch with its delay slot unfilled, set `nullify'
- as it can nullify the delay slot and save a nop. */
- if (length == 8 && dbr_sequence_length () == 0)
- nullify = 1;
-
- /* If this is a short forward conditional branch which did not get
- its delay slot filled, the delay slot can still be nullified. */
- if (! nullify && length == 4 && dbr_sequence_length () == 0)
- nullify = forward_branch_p (insn);
-
- /* Handle short versions first. */
- if (length == 4 && nullify)
- return "movb,%C2,n %1,%0,%3";
- else if (length == 4 && ! nullify)
- return "movb,%C2 %1,%0,%3";
- else if (length == 8)
- {
- /* Handle weird backwards branch with a filled delay slot
- which is nullified. */
- if (dbr_sequence_length () != 0
- && ! forward_branch_p (insn)
- && nullify)
- return "movb,%N2,n %1,%0,.+12\n\tbl %3,0";
-
- /* Handle short backwards branch with an unfilled delay slot.
- Using a movb;nop rather than or;bl saves 1 cycle for both
- taken and untaken branches. */
- else if (dbr_sequence_length () == 0
- && ! forward_branch_p (insn)
- && insn_addresses
- && VAL_14_BITS_P (insn_addresses[INSN_UID (JUMP_LABEL (insn))]
- - insn_addresses[INSN_UID (insn)] - 8))
- return "movb,%C2 %1,%0,%3%#";
- /* Handle normal cases. */
- if (nullify)
- return "or,%N2 %1,%%r0,%0\n\tbl,n %3,0";
- else
- return "or,%N2 %1,%%r0,%0\n\tbl %3,0";
- }
- else
- abort();
- }
- /* Deal with gross reload from FP register case. */
- else if (which_alternative == 1)
- {
- /* Move loop counter from FP register to MEM then into a GR,
- increment the GR, store the GR into MEM, and finally reload
- the FP register from MEM from within the branch's delay slot. */
- output_asm_insn ("stw %1,-16(0,%%r30)",operands);
- if (get_attr_length (insn) == 12)
- return "comb,%S2 0,%1,%3\n\tfldws -16(0,%%r30),%0";
- else
- return "comclr,%B2 0,%1,0\n\tbl %3,0\n\tfldws -16(0,%%r30),%0";
- }
- /* Deal with gross reload from memory case. */
- else if (which_alternative == 2)
- {
- /* Reload loop counter from memory, the store back to memory
- happens in the branch's delay slot. */
- if (get_attr_length (insn) == 8)
- return "comb,%S2 0,%1,%3\n\tstw %1,%0";
- else
- return "comclr,%B2 0,%1,0\n\tbl %3,0\n\tstw %1,%0";
- }
- /* Handle SAR as a destination. */
- else
- {
- if (get_attr_length (insn) == 8)
- return "comb,%S2 0,%1,%3\n\tmtsar %r1";
- else
- return "comclr,%B2 0,%1,0\n\tbl %3,0\n\tmtsar %r1";
- }
-}
-
-
-/* INSN is a millicode call. It may have an unconditional jump in its delay
- slot.
-
- CALL_DEST is the routine we are calling. */
-
-char *
-output_millicode_call (insn, call_dest)
- rtx insn;
- rtx call_dest;
-{
- int distance;
- rtx xoperands[4];
- rtx seq_insn;
-
- /* Handle common case -- empty delay slot or no jump in the delay slot,
- and we're sure that the branch will reach the beginning of the $CODE$
- subspace. */
- if ((dbr_sequence_length () == 0
- && (get_attr_length (insn) == 8 || get_attr_length (insn) == 28))
- || (dbr_sequence_length () != 0
- && GET_CODE (NEXT_INSN (insn)) != JUMP_INSN
- && get_attr_length (insn) == 4))
- {
- xoperands[0] = call_dest;
- output_asm_insn ("bl %0,%%r31%#", xoperands);
- return "";
- }
-
- /* This call may not reach the beginning of the $CODE$ subspace. */
- if (get_attr_length (insn) > 4)
- {
- int delay_insn_deleted = 0;
- rtx xoperands[2];
-
- /* We need to emit an inline long-call branch. */
- if (dbr_sequence_length () != 0
- && GET_CODE (NEXT_INSN (insn)) != JUMP_INSN)
- {
- /* A non-jump insn in the delay slot. By definition we can
- emit this insn before the call. */
- final_scan_insn (NEXT_INSN (insn), asm_out_file, optimize, 0, 0);
-
- /* Now delete the delay insn. */
- PUT_CODE (NEXT_INSN (insn), NOTE);
- NOTE_LINE_NUMBER (NEXT_INSN (insn)) = NOTE_INSN_DELETED;
- NOTE_SOURCE_FILE (NEXT_INSN (insn)) = 0;
- delay_insn_deleted = 1;
- }
-
- /* If we're allowed to use be/ble instructions, then this is the
- best sequence to use for a long millicode call. */
- if (TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS
- || ! (flag_pic || TARGET_PORTABLE_RUNTIME))
- {
- xoperands[0] = call_dest;
- output_asm_insn ("ldil L%%%0,%%r31", xoperands);
- output_asm_insn ("ble R%%%0(%%sr4,%%r31)", xoperands);
- output_asm_insn ("nop", xoperands);
- }
- /* Pure portable runtime doesn't allow be/ble; we also don't have
- PIC support int he assembler/linker, so this sequence is needed. */
- else if (TARGET_PORTABLE_RUNTIME)
- {
- xoperands[0] = call_dest;
- /* Get the address of our target into %r29. */
- output_asm_insn ("ldil L%%%0,%%r29", xoperands);
- output_asm_insn ("ldo R%%%0(%%r29),%%r29", xoperands);
-
- /* Get our return address into %r31. */
- output_asm_insn ("blr 0,%%r31", xoperands);
-
- /* Jump to our target address in %r29. */
- output_asm_insn ("bv,n 0(%%r29)", xoperands);
-
- /* Empty delay slot. Note this insn gets fetched twice and
- executed once. To be safe we use a nop. */
- output_asm_insn ("nop", xoperands);
- return "";
- }
- /* PIC long millicode call sequence. */
- else
- {
- xoperands[0] = call_dest;
- xoperands[1] = gen_label_rtx ();
- /* Get our address + 8 into %r1. */
- output_asm_insn ("bl .+8,%%r1", xoperands);
-
- /* Add %r1 to the offset of our target from the next insn. */
- output_asm_insn ("addil L%%%0-%1,%%r1", xoperands);
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
- CODE_LABEL_NUMBER (xoperands[1]));
- output_asm_insn ("ldo R%%%0-%1(%%r1),%%r1", xoperands);
-
- /* Get the return address into %r31. */
- output_asm_insn ("blr 0,%%r31", xoperands);
-
- /* Branch to our target which is in %r1. */
- output_asm_insn ("bv,n 0(%%r1)", xoperands);
-
- /* Empty delay slot. Note this insn gets fetched twice and
- executed once. To be safe we use a nop. */
- output_asm_insn ("nop", xoperands);
- }
-
- /* If we had a jump in the call's delay slot, output it now. */
- if (dbr_sequence_length () != 0
- && !delay_insn_deleted)
- {
- xoperands[0] = XEXP (PATTERN (NEXT_INSN (insn)), 1);
- output_asm_insn ("b,n %0", xoperands);
-
- /* Now delete the delay insn. */
- PUT_CODE (NEXT_INSN (insn), NOTE);
- NOTE_LINE_NUMBER (NEXT_INSN (insn)) = NOTE_INSN_DELETED;
- NOTE_SOURCE_FILE (NEXT_INSN (insn)) = 0;
- }
- return "";
- }
-
- /* This call has an unconditional jump in its delay slot and the
- call is known to reach its target or the beginning of the current
- subspace. */
-
- /* Use the containing sequence insn's address. */
- seq_insn = NEXT_INSN (PREV_INSN (XVECEXP (final_sequence, 0, 0)));
-
- distance = insn_addresses[INSN_UID (JUMP_LABEL (NEXT_INSN (insn)))]
- - insn_addresses[INSN_UID (seq_insn)] - 8;
-
- /* If the branch was too far away, emit a normal call followed
- by a nop, followed by the unconditional branch.
-
- If the branch is close, then adjust %r2 from within the
- call's delay slot. */
-
- xoperands[0] = call_dest;
- xoperands[1] = XEXP (PATTERN (NEXT_INSN (insn)), 1);
- if (! VAL_14_BITS_P (distance))
- output_asm_insn ("bl %0,%%r31\n\tnop\n\tbl,n %1,%%r0", xoperands);
- else
- {
- xoperands[3] = gen_label_rtx ();
- output_asm_insn ("\n\tbl %0,%%r31\n\tldo %1-%3(%%r31),%%r31", xoperands);
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
- CODE_LABEL_NUMBER (xoperands[3]));
- }
-
- /* Delete the jump. */
- PUT_CODE (NEXT_INSN (insn), NOTE);
- NOTE_LINE_NUMBER (NEXT_INSN (insn)) = NOTE_INSN_DELETED;
- NOTE_SOURCE_FILE (NEXT_INSN (insn)) = 0;
- return "";
-}
-
-extern struct obstack permanent_obstack;
-extern struct obstack *saveable_obstack;
-extern struct obstack *rtl_obstack;
-extern struct obstack *current_obstack;
-
-/* INSN is either a function call. It may have an unconditional jump
- in its delay slot.
-
- CALL_DEST is the routine we are calling. */
-
-char *
-output_call (insn, call_dest)
- rtx insn;
- rtx call_dest;
-{
- int distance;
- rtx xoperands[4];
- rtx seq_insn;
-
- /* Handle common case -- empty delay slot or no jump in the delay slot,
- and we're sure that the branch will reach the beginning of the $CODE$
- subspace. */
- if ((dbr_sequence_length () == 0
- && get_attr_length (insn) == 8)
- || (dbr_sequence_length () != 0
- && GET_CODE (NEXT_INSN (insn)) != JUMP_INSN
- && get_attr_length (insn) == 4))
- {
- xoperands[0] = call_dest;
- output_asm_insn ("bl %0,%%r2%#", xoperands);
- return "";
- }
-
- /* This call may not reach the beginning of the $CODE$ subspace. */
- if (get_attr_length (insn) > 8)
- {
- int delay_insn_deleted = 0;
- rtx xoperands[2];
- rtx link;
-
- /* We need to emit an inline long-call branch. Furthermore,
- because we're changing a named function call into an indirect
- function call well after the parameters have been set up, we
- need to make sure any FP args appear in both the integer
- and FP registers. Also, we need move any delay slot insn
- out of the delay slot. And finally, we can't rely on the linker
- being able to fix the call to $$dyncall! -- Yuk!. */
- if (dbr_sequence_length () != 0
- && GET_CODE (NEXT_INSN (insn)) != JUMP_INSN)
- {
- /* A non-jump insn in the delay slot. By definition we can
- emit this insn before the call (and in fact before argument
- relocating. */
- final_scan_insn (NEXT_INSN (insn), asm_out_file, optimize, 0, 0);
-
- /* Now delete the delay insn. */
- PUT_CODE (NEXT_INSN (insn), NOTE);
- NOTE_LINE_NUMBER (NEXT_INSN (insn)) = NOTE_INSN_DELETED;
- NOTE_SOURCE_FILE (NEXT_INSN (insn)) = 0;
- delay_insn_deleted = 1;
- }
-
- /* Now copy any FP arguments into integer registers. */
- for (link = CALL_INSN_FUNCTION_USAGE (insn); link; link = XEXP (link, 1))
- {
- int arg_mode, regno;
- rtx use = XEXP (link, 0);
- if (! (GET_CODE (use) == USE
- && GET_CODE (XEXP (use, 0)) == REG
- && FUNCTION_ARG_REGNO_P (REGNO (XEXP (use, 0)))))
- continue;
-
- arg_mode = GET_MODE (XEXP (use, 0));
- regno = REGNO (XEXP (use, 0));
- /* Is it a floating point register? */
- if (regno >= 32 && regno <= 39)
- {
- /* Copy from the FP register into an integer register
- (via memory). */
- if (arg_mode == SFmode)
- {
- xoperands[0] = XEXP (use, 0);
- xoperands[1] = gen_rtx_REG (SImode, 26 - (regno - 32) / 2);
- output_asm_insn ("fstws %0,-16(%%sr0,%%r30)", xoperands);
- output_asm_insn ("ldw -16(%%sr0,%%r30),%1", xoperands);
- }
- else
- {
- xoperands[0] = XEXP (use, 0);
- xoperands[1] = gen_rtx_REG (DImode, 25 - (regno - 34) / 2);
- output_asm_insn ("fstds %0,-16(%%sr0,%%r30)", xoperands);
- output_asm_insn ("ldw -12(%%sr0,%%r30),%R1", xoperands);
- output_asm_insn ("ldw -16(%%sr0,%%r30),%1", xoperands);
- }
- }
- }
-
- /* Don't have to worry about TARGET_PORTABLE_RUNTIME here since
- we don't have any direct calls in that case. */
- {
- int i;
- char *name = XSTR (call_dest, 0);
-
- /* See if we have already put this function on the list
- of deferred plabels. This list is generally small,
- so a liner search is not too ugly. If it proves too
- slow replace it with something faster. */
- for (i = 0; i < n_deferred_plabels; i++)
- if (strcmp (name, deferred_plabels[i].name) == 0)
- break;
-
- /* If the deferred plabel list is empty, or this entry was
- not found on the list, create a new entry on the list. */
- if (deferred_plabels == NULL || i == n_deferred_plabels)
- {
- struct obstack *ambient_obstack = current_obstack;
- struct obstack *ambient_rtl_obstack = rtl_obstack;
- char *real_name;
-
- /* Any RTL we create here needs to live until the end of
- the compilation unit and therefore must live on the
- permanent obstack. */
- current_obstack = &permanent_obstack;
- rtl_obstack = &permanent_obstack;
-
- if (deferred_plabels == 0)
- deferred_plabels = (struct deferred_plabel *)
- xmalloc (1 * sizeof (struct deferred_plabel));
- else
- deferred_plabels = (struct deferred_plabel *)
- xrealloc (deferred_plabels,
- ((n_deferred_plabels + 1)
- * sizeof (struct deferred_plabel)));
-
- i = n_deferred_plabels++;
- deferred_plabels[i].internal_label = gen_label_rtx ();
- deferred_plabels[i].name = obstack_alloc (&permanent_obstack,
- strlen (name) + 1);
- strcpy (deferred_plabels[i].name, name);
-
- /* Switch back to normal obstack allocation. */
- current_obstack = ambient_obstack;
- rtl_obstack = ambient_rtl_obstack;
-
- /* Gross. We have just implicitly taken the address of this
- function, mark it as such. */
- STRIP_NAME_ENCODING (real_name, name);
- TREE_SYMBOL_REFERENCED (get_identifier (real_name)) = 1;
- }
-
- /* We have to load the address of the function using a procedure
- label (plabel). Inline plabels can lose for PIC and other
- cases, so avoid them by creating a 32bit plabel in the data
- segment. */
- if (flag_pic)
- {
- xoperands[0] = deferred_plabels[i].internal_label;
- xoperands[1] = gen_label_rtx ();
-
- output_asm_insn ("addil LT%%%0,%%r19", xoperands);
- output_asm_insn ("ldw RT%%%0(%%r1),%%r22", xoperands);
- output_asm_insn ("ldw 0(0,%%r22),%%r22", xoperands);
-
- /* Get our address + 8 into %r1. */
- output_asm_insn ("bl .+8,%%r1", xoperands);
-
- /* Add %r1 to the offset of dyncall from the next insn. */
- output_asm_insn ("addil L%%$$dyncall-%1,%%r1", xoperands);
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
- CODE_LABEL_NUMBER (xoperands[1]));
- output_asm_insn ("ldo R%%$$dyncall-%1(%%r1),%%r1", xoperands);
-
- /* Get the return address into %r31. */
- output_asm_insn ("blr 0,%%r31", xoperands);
-
- /* Branch to our target which is in %r1. */
- output_asm_insn ("bv 0(%%r1)", xoperands);
-
- /* Copy the return address into %r2 also. */
- output_asm_insn ("copy %%r31,%%r2", xoperands);
- }
- else
- {
- xoperands[0] = deferred_plabels[i].internal_label;
-
- /* Get the address of our target into %r22. */
- output_asm_insn ("addil LR%%%0-$global$,%%r27", xoperands);
- output_asm_insn ("ldw RR%%%0-$global$(%%r1),%%r22", xoperands);
-
- /* Get the high part of the address of $dyncall into %r2, then
- add in the low part in the branch instruction. */
- output_asm_insn ("ldil L%%$$dyncall,%%r2", xoperands);
- output_asm_insn ("ble R%%$$dyncall(%%sr4,%%r2)", xoperands);
-
- /* Copy the return pointer into both %r31 and %r2. */
- output_asm_insn ("copy %%r31,%%r2", xoperands);
- }
- }
-
- /* If we had a jump in the call's delay slot, output it now. */
- if (dbr_sequence_length () != 0
- && !delay_insn_deleted)
- {
- xoperands[0] = XEXP (PATTERN (NEXT_INSN (insn)), 1);
- output_asm_insn ("b,n %0", xoperands);
-
- /* Now delete the delay insn. */
- PUT_CODE (NEXT_INSN (insn), NOTE);
- NOTE_LINE_NUMBER (NEXT_INSN (insn)) = NOTE_INSN_DELETED;
- NOTE_SOURCE_FILE (NEXT_INSN (insn)) = 0;
- }
- return "";
- }
-
- /* This call has an unconditional jump in its delay slot and the
- call is known to reach its target or the beginning of the current
- subspace. */
-
- /* Use the containing sequence insn's address. */
- seq_insn = NEXT_INSN (PREV_INSN (XVECEXP (final_sequence, 0, 0)));
-
- distance = insn_addresses[INSN_UID (JUMP_LABEL (NEXT_INSN (insn)))]
- - insn_addresses[INSN_UID (seq_insn)] - 8;
-
- /* If the branch was too far away, emit a normal call followed
- by a nop, followed by the unconditional branch.
-
- If the branch is close, then adjust %r2 from within the
- call's delay slot. */
-
- xoperands[0] = call_dest;
- xoperands[1] = XEXP (PATTERN (NEXT_INSN (insn)), 1);
- if (! VAL_14_BITS_P (distance))
- output_asm_insn ("bl %0,%%r2\n\tnop\n\tbl,n %1,%%r0", xoperands);
- else
- {
- xoperands[3] = gen_label_rtx ();
- output_asm_insn ("\n\tbl %0,%%r2\n\tldo %1-%3(%%r2),%%r2", xoperands);
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, "L",
- CODE_LABEL_NUMBER (xoperands[3]));
- }
-
- /* Delete the jump. */
- PUT_CODE (NEXT_INSN (insn), NOTE);
- NOTE_LINE_NUMBER (NEXT_INSN (insn)) = NOTE_INSN_DELETED;
- NOTE_SOURCE_FILE (NEXT_INSN (insn)) = 0;
- return "";
-}
-
-/* In HPUX 8.0's shared library scheme, special relocations are needed
- for function labels if they might be passed to a function
- in a shared library (because shared libraries don't live in code
- space), and special magic is needed to construct their address.
-
- For reasons too disgusting to describe storage for the new name
- is allocated either on the saveable_obstack (released at function
- exit) or on the permanent_obstack for things that can never change
- (libcall names for example). */
-
-void
-hppa_encode_label (sym, permanent)
- rtx sym;
- int permanent;
-{
- char *str = XSTR (sym, 0);
- int len = strlen (str);
- char *newstr;
-
- newstr = obstack_alloc ((permanent ? &permanent_obstack : saveable_obstack),
- len + 2);
-
- if (str[0] == '*')
- *newstr++ = *str++;
- strcpy (newstr + 1, str);
- *newstr = '@';
- XSTR (sym,0) = newstr;
-}
-
-int
-function_label_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
-{
- return GET_CODE (op) == SYMBOL_REF && FUNCTION_NAME_P (XSTR (op, 0));
-}
-
-/* Returns 1 if OP is a function label involved in a simple addition
- with a constant. Used to keep certain patterns from matching
- during instruction combination. */
-int
-is_function_label_plus_const (op)
- rtx op;
-{
- /* Strip off any CONST. */
- if (GET_CODE (op) == CONST)
- op = XEXP (op, 0);
-
- return (GET_CODE (op) == PLUS
- && function_label_operand (XEXP (op, 0), Pmode)
- && GET_CODE (XEXP (op, 1)) == CONST_INT);
-}
-
-/* Returns 1 if the 6 operands specified in OPERANDS are suitable for
- use in fmpyadd instructions. */
-int
-fmpyaddoperands (operands)
- rtx *operands;
-{
- enum machine_mode mode = GET_MODE (operands[0]);
-
- /* Must be a floating point mode. */
- if (mode != SFmode && mode != DFmode)
- return 0;
-
- /* All modes must be the same. */
- if (! (mode == GET_MODE (operands[1])
- && mode == GET_MODE (operands[2])
- && mode == GET_MODE (operands[3])
- && mode == GET_MODE (operands[4])
- && mode == GET_MODE (operands[5])))
- return 0;
-
- /* All operands must be registers. */
- if (! (GET_CODE (operands[1]) == REG
- && GET_CODE (operands[2]) == REG
- && GET_CODE (operands[3]) == REG
- && GET_CODE (operands[4]) == REG
- && GET_CODE (operands[5]) == REG))
- return 0;
-
- /* Only 2 real operands to the addition. One of the input operands must
- be the same as the output operand. */
- if (! rtx_equal_p (operands[3], operands[4])
- && ! rtx_equal_p (operands[3], operands[5]))
- return 0;
-
- /* Inout operand of add can not conflict with any operands from multiply. */
- if (rtx_equal_p (operands[3], operands[0])
- || rtx_equal_p (operands[3], operands[1])
- || rtx_equal_p (operands[3], operands[2]))
- return 0;
-
- /* multiply can not feed into addition operands. */
- if (rtx_equal_p (operands[4], operands[0])
- || rtx_equal_p (operands[5], operands[0]))
- return 0;
-
- /* SFmode limits the registers to the upper 32 of the 32bit FP regs. */
- if (mode == SFmode
- && (REGNO (operands[0]) < 57
- || REGNO (operands[1]) < 57
- || REGNO (operands[2]) < 57
- || REGNO (operands[3]) < 57
- || REGNO (operands[4]) < 57
- || REGNO (operands[5]) < 57))
- return 0;
-
- /* Passed. Operands are suitable for fmpyadd. */
- return 1;
-}
-
-/* Returns 1 if the 6 operands specified in OPERANDS are suitable for
- use in fmpysub instructions. */
-int
-fmpysuboperands (operands)
- rtx *operands;
-{
- enum machine_mode mode = GET_MODE (operands[0]);
-
- /* Must be a floating point mode. */
- if (mode != SFmode && mode != DFmode)
- return 0;
-
- /* All modes must be the same. */
- if (! (mode == GET_MODE (operands[1])
- && mode == GET_MODE (operands[2])
- && mode == GET_MODE (operands[3])
- && mode == GET_MODE (operands[4])
- && mode == GET_MODE (operands[5])))
- return 0;
-
- /* All operands must be registers. */
- if (! (GET_CODE (operands[1]) == REG
- && GET_CODE (operands[2]) == REG
- && GET_CODE (operands[3]) == REG
- && GET_CODE (operands[4]) == REG
- && GET_CODE (operands[5]) == REG))
- return 0;
-
- /* Only 2 real operands to the subtraction. Subtraction is not a commutative
- operation, so operands[4] must be the same as operand[3]. */
- if (! rtx_equal_p (operands[3], operands[4]))
- return 0;
-
- /* multiply can not feed into subtraction. */
- if (rtx_equal_p (operands[5], operands[0]))
- return 0;
-
- /* Inout operand of sub can not conflict with any operands from multiply. */
- if (rtx_equal_p (operands[3], operands[0])
- || rtx_equal_p (operands[3], operands[1])
- || rtx_equal_p (operands[3], operands[2]))
- return 0;
-
- /* SFmode limits the registers to the upper 32 of the 32bit FP regs. */
- if (mode == SFmode
- && (REGNO (operands[0]) < 57
- || REGNO (operands[1]) < 57
- || REGNO (operands[2]) < 57
- || REGNO (operands[3]) < 57
- || REGNO (operands[4]) < 57
- || REGNO (operands[5]) < 57))
- return 0;
-
- /* Passed. Operands are suitable for fmpysub. */
- return 1;
-}
-
-int
-plus_xor_ior_operator (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
-{
- return (GET_CODE (op) == PLUS || GET_CODE (op) == XOR
- || GET_CODE (op) == IOR);
-}
-
-/* Return 1 if the given constant is 2, 4, or 8. These are the valid
- constants for shadd instructions. */
-static int
-shadd_constant_p (val)
- int val;
-{
- if (val == 2 || val == 4 || val == 8)
- return 1;
- else
- return 0;
-}
-
-/* Return 1 if OP is a CONST_INT with the value 2, 4, or 8. These are
- the valid constant for shadd instructions. */
-int
-shadd_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
-{
- return (GET_CODE (op) == CONST_INT && shadd_constant_p (INTVAL (op)));
-}
-
-/* Return 1 if OP is valid as a base register in a reg + reg address. */
-
-int
-basereg_operand (op, mode)
- rtx op;
- enum machine_mode mode;
-{
- /* cse will create some unscaled indexed addresses, however; it
- generally isn't a win on the PA, so avoid creating unscaled
- indexed addresses until after cse is finished. */
- if (!cse_not_expected)
- return 0;
-
- /* Once reload has started everything is considered valid. Reload should
- only create indexed addresses using the stack/frame pointer, and any
- others were checked for validity when created by the combine pass.
-
- Also allow any register when TARGET_NO_SPACE_REGS is in effect since
- we don't have to worry about the braindamaged implicit space register
- selection using the basereg only (rather than effective address)
- screwing us over. */
- if (TARGET_NO_SPACE_REGS || reload_in_progress || reload_completed)
- return (GET_CODE (op) == REG);
-
- /* Stack is always OK for indexing. */
- if (op == stack_pointer_rtx)
- return 1;
-
- /* While it's always safe to index off the frame pointer, it's not
- always profitable, particularly when the frame pointer is being
- eliminated. */
- if (! flag_omit_frame_pointer && op == frame_pointer_rtx)
- return 1;
-
- /* The only other valid OPs are pseudo registers with
- REGNO_POINTER_FLAG set. */
- if (GET_CODE (op) != REG
- || REGNO (op) < FIRST_PSEUDO_REGISTER
- || ! register_operand (op, mode))
- return 0;
-
- return REGNO_POINTER_FLAG (REGNO (op));
-}
-
-/* Return 1 if this operand is anything other than a hard register. */
-
-int
-non_hard_reg_operand (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
-{
- return ! (GET_CODE (op) == REG && REGNO (op) < FIRST_PSEUDO_REGISTER);
-}
-
-/* Return 1 if INSN branches forward. Should be using insn_addresses
- to avoid walking through all the insns... */
-static int
-forward_branch_p (insn)
- rtx insn;
-{
- rtx label = JUMP_LABEL (insn);
-
- while (insn)
- {
- if (insn == label)
- break;
- else
- insn = NEXT_INSN (insn);
- }
-
- return (insn == label);
-}
-
-/* Return 1 if OP is an equality comparison, else return 0. */
-int
-eq_neq_comparison_operator (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
-{
- return (GET_CODE (op) == EQ || GET_CODE (op) == NE);
-}
-
-/* Return 1 if OP is an operator suitable for use in a movb instruction. */
-int
-movb_comparison_operator (op, mode)
- rtx op;
- enum machine_mode mode ATTRIBUTE_UNUSED;
-{
- return (GET_CODE (op) == EQ || GET_CODE (op) == NE
- || GET_CODE (op) == LT || GET_CODE (op) == GE);
-}
-
-/* Return 1 if INSN is in the delay slot of a call instruction. */
-int
-jump_in_call_delay (insn)
- rtx insn;
-{
-
- if (GET_CODE (insn) != JUMP_INSN)
- return 0;
-
- if (PREV_INSN (insn)
- && PREV_INSN (PREV_INSN (insn))
- && GET_CODE (next_active_insn (PREV_INSN (PREV_INSN (insn)))) == INSN)
- {
- rtx test_insn = next_active_insn (PREV_INSN (PREV_INSN (insn)));
-
- return (GET_CODE (PATTERN (test_insn)) == SEQUENCE
- && XVECEXP (PATTERN (test_insn), 0, 1) == insn);
-
- }
- else
- return 0;
-}
-
-/* Output an unconditional move and branch insn. */
-
-char *
-output_parallel_movb (operands, length)
- rtx *operands;
- int length;
-{
- /* These are the cases in which we win. */
- if (length == 4)
- return "mov%I1b,tr %1,%0,%2";
-
- /* None of these cases wins, but they don't lose either. */
- if (dbr_sequence_length () == 0)
- {
- /* Nothing in the delay slot, fake it by putting the combined
- insn (the copy or add) in the delay slot of a bl. */
- if (GET_CODE (operands[1]) == CONST_INT)
- return "bl %2,0\n\tldi %1,%0";
- else
- return "bl %2,0\n\tcopy %1,%0";
- }
- else
- {
- /* Something in the delay slot, but we've got a long branch. */
- if (GET_CODE (operands[1]) == CONST_INT)
- return "ldi %1,%0\n\tbl %2,0";
- else
- return "copy %1,%0\n\tbl %2,0";
- }
-}
-
-/* Output an unconditional add and branch insn. */
-
-char *
-output_parallel_addb (operands, length)
- rtx *operands;
- int length;
-{
- /* To make life easy we want operand0 to be the shared input/output
- operand and operand1 to be the readonly operand. */
- if (operands[0] == operands[1])
- operands[1] = operands[2];
-
- /* These are the cases in which we win. */
- if (length == 4)
- return "add%I1b,tr %1,%0,%3";
-
- /* None of these cases win, but they don't lose either. */
- if (dbr_sequence_length () == 0)
- {
- /* Nothing in the delay slot, fake it by putting the combined
- insn (the copy or add) in the delay slot of a bl. */
- return "bl %3,0\n\tadd%I1 %1,%0,%0";
- }
- else
- {
- /* Something in the delay slot, but we've got a long branch. */
- return "add%I1 %1,%0,%0\n\tbl %3,0";
- }
-}
-
-/* Return nonzero if INSN (a jump insn) immediately follows a call to
- a named function. This is used to discourage creating parallel movb/addb
- insns since a jump which immediately follows a call can execute in the
- delay slot of the call.
-
- It is also used to avoid filling the delay slot of a jump which
- immediately follows a call since the jump can usually be eliminated
- completely by modifying RP in the delay slot of the call. */
-
-int
-following_call (insn)
- rtx insn;
-{
- /* CYGNUS LOCAL PA8000/law */
- /* We do not parallel movb,addb or place jumps into call delay slots when
- optimizing for the PA8000. */
- if (pa_cpu != PROCESSOR_8000)
- return 0;
- /* END CYGNUS LOCAL */
-
- /* Find the previous real insn, skipping NOTEs. */
- insn = PREV_INSN (insn);
- while (insn && GET_CODE (insn) == NOTE)
- insn = PREV_INSN (insn);
-
- /* Check for CALL_INSNs and millicode calls. */
- if (insn
- && ((GET_CODE (insn) == CALL_INSN
- && get_attr_type (insn) != TYPE_DYNCALL)
- || (GET_CODE (insn) == INSN
- && GET_CODE (PATTERN (insn)) != SEQUENCE
- && GET_CODE (PATTERN (insn)) != USE
- && GET_CODE (PATTERN (insn)) != CLOBBER
- && get_attr_type (insn) == TYPE_MILLI)))
- return 1;
-
- return 0;
-}
-
-/* Restore any INSN_CODEs for insns with unscaled indexed addresses since
- the INSN_CODE might be clobberd by rerecognition triggered by reorg. */
-
-static void
-restore_unscaled_index_insn_codes (insns)
- rtx insns;
-{
- rtx insn;
-
- for (insn = insns; insn; insn = NEXT_INSN (insn))
- {
- if (INSN_UID (insn) < max_unscaled_index_insn_codes_uid
- && unscaled_index_insn_codes[INSN_UID (insn)] != -1)
- INSN_CODE (insn) = unscaled_index_insn_codes[INSN_UID (insn)];
- }
-}
-
-/* Severe braindamage:
-
- On the PA, address computations within MEM expressions are not
- commutative because of the implicit space register selection
- from the base register (instead of the entire effective address).
-
- Because of this mis-feature we have to know which register in a reg+reg
- address is the base and which is the index.
-
- Before reload, the base can be identified by REGNO_POINTER_FLAG. We use
- this to force base + index addresses to match a different insn than
- index + base addresses.
-
- We assume that no pass during or after reload creates new unscaled indexed
- addresses, so any unscaled indexed address we find after reload must have
- at one time been recognized a base + index or index + base and we accept
- any register as a base register.
-
- This scheme assumes that no pass during/after reload will rerecognize an
- insn with an unscaled indexed address. This failed due to a reorg call
- to rerecognize certain insns.
-
- So, we record if an insn uses an unscaled indexed address and which
- register is the base (via recording of the INSN_CODE for such insns).
-
- Just before we output code for the function, we make sure all the insns
- using unscaled indexed addresses have the same INSN_CODE as they did
- immediately before delay slot scheduling.
-
- This is extremely gross. Long term, I'd like to be able to look at
- REG_POINTER_FLAG to handle these kinds of problems. */
-
-static void
-record_unscaled_index_insn_codes (insns)
- rtx insns;
-{
- rtx insn;
-
- max_unscaled_index_insn_codes_uid = get_max_uid ();
- unscaled_index_insn_codes
- = (int *)xmalloc (max_unscaled_index_insn_codes_uid * sizeof (int));
- memset (unscaled_index_insn_codes, -1,
- max_unscaled_index_insn_codes_uid * sizeof (int));
-
- for (insn = insns; insn; insn = NEXT_INSN (insn))
- {
- rtx set = single_set (insn);
- rtx mem = NULL_RTX;
-
- /* Ignore anything that isn't a normal SET. */
- if (set == NULL_RTX)
- continue;
-
- /* No insns can have more than one MEM. */
- if (GET_CODE (SET_SRC (set)) == MEM)
- mem = SET_SRC (set);
-
- if (GET_CODE (SET_DEST (set)) == MEM)
- mem = SET_DEST (set);
-
- /* If neither operand is a mem, then there's nothing to do. */
- if (mem == NULL_RTX)
- continue;
-
- if (GET_CODE (XEXP (mem, 0)) != PLUS)
- continue;
-
- /* If both are REGs (or SUBREGs), then record the insn code for
- this insn. */
- if (REG_P (XEXP (XEXP (mem, 0), 0)) && REG_P (XEXP (XEXP (mem, 0), 1)))
- unscaled_index_insn_codes[INSN_UID (insn)] = INSN_CODE (insn);
- }
-}
-
-/* We use this hook to perform a PA specific optimization which is difficult
- to do in earlier passes.
-
- We want the delay slots of branches within jump tables to be filled.
- None of the compiler passes at the moment even has the notion that a
- PA jump table doesn't contain addresses, but instead contains actual
- instructions!
-
- Because we actually jump into the table, the addresses of each entry
- must stay constant in relation to the beginning of the table (which
- itself must stay constant relative to the instruction to jump into
- it). I don't believe we can guarantee earlier passes of the compiler
- will adhere to those rules.
-
- So, late in the compilation process we find all the jump tables, and
- expand them into real code -- eg each entry in the jump table vector
- will get an appropriate label followed by a jump to the final target.
-
- Reorg and the final jump pass can then optimize these branches and
- fill their delay slots. We end up with smaller, more efficient code.
-
- The jump instructions within the table are special; we must be able
- to identify them during assembly output (if the jumps don't get filled
- we need to emit a nop rather than nullifying the delay slot)). We
- identify jumps in switch tables by marking the SET with DImode.
-
- We also surround the jump table itself with BEGIN_BRTAB and END_BRTAB
- insns. This serves two purposes, first it prevents jump.c from
- noticing that the last N entries in the table jump to the instruction
- immediately after the table and deleting the jumps. Second, those
- insns mark where we should emit .begin_brtab and .end_brtab directives
- when using GAS (allows for better link time optimizations). */
-
-void
-pa_reorg (insns)
- rtx insns;
-{
- rtx insn;
-
- /* Keep track of which insns have unscaled indexed addresses, and which
- register is the base address in such insns. */
- record_unscaled_index_insn_codes (insns);
-
- remove_useless_addtr_insns (insns, 1);
-
- /* CYGNUS LOCAL PA8000/law */
- /* These optimizations hurt PA8000 performance. */
- if (pa_cpu != PROCESSOR_8000)
- pa_combine_instructions (get_insns ());
- /* END CYGNUS LOCAL */
-
- /* This is fairly cheap, so always run it if optimizing. */
- if (optimize > 0 && !TARGET_BIG_SWITCH)
- {
- /* Find and explode all ADDR_VEC or ADDR_DIFF_VEC insns. */
- insns = get_insns ();
- for (insn = insns; insn; insn = NEXT_INSN (insn))
- {
- rtx pattern, tmp, location;
- unsigned int length, i;
-
- /* Find an ADDR_VEC or ADDR_DIFF_VEC insn to explode. */
- if (GET_CODE (insn) != JUMP_INSN
- || (GET_CODE (PATTERN (insn)) != ADDR_VEC
- && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC))
- continue;
-
- /* Emit marker for the beginning of the branch table. */
- emit_insn_before (gen_begin_brtab (), insn);
-
- pattern = PATTERN (insn);
- location = PREV_INSN (insn);
- length = XVECLEN (pattern, GET_CODE (pattern) == ADDR_DIFF_VEC);
-
- for (i = 0; i < length; i++)
- {
- /* Emit a label before each jump to keep jump.c from
- removing this code. */
- tmp = gen_label_rtx ();
- LABEL_NUSES (tmp) = 1;
- emit_label_after (tmp, location);
- location = NEXT_INSN (location);
-
- if (GET_CODE (pattern) == ADDR_VEC)
- {
- /* Emit the jump itself. */
- tmp = gen_jump (XEXP (XVECEXP (pattern, 0, i), 0));
- tmp = emit_jump_insn_after (tmp, location);
- JUMP_LABEL (tmp) = XEXP (XVECEXP (pattern, 0, i), 0);
- /* It is easy to rely on the branch table markers
- during assembly output to trigger the correct code
- for a switch table jump with an unfilled delay slot,
-
- However, that requires state and assumes that we look
- at insns in order.
-
- We can't make such assumptions when computing the length
- of instructions. Ugh. We could walk the insn chain to
- determine if this instruction is in a branch table, but
- that can get rather expensive, particularly during the
- branch shortening phase of the compiler.
-
- So instead we mark this jump as being special. This is
- far from ideal and knows that no code after this will
- muck around with the mode of the JUMP_INSN itself. */
- PUT_MODE (tmp, SImode);
- LABEL_NUSES (JUMP_LABEL (tmp))++;
- location = NEXT_INSN (location);
- }
- else
- {
- /* Emit the jump itself. */
- tmp = gen_jump (XEXP (XVECEXP (pattern, 1, i), 0));
- tmp = emit_jump_insn_after (tmp, location);
- JUMP_LABEL (tmp) = XEXP (XVECEXP (pattern, 1, i), 0);
- /* It is easy to rely on the branch table markers
- during assembly output to trigger the correct code
- for a switch table jump with an unfilled delay slot,
-
- However, that requires state and assumes that we look
- at insns in order.
-
- We can't make such assumptions when computing the length
- of instructions. Ugh. We could walk the insn chain to
- determine if this instruction is in a branch table, but
- that can get rather expensive, particularly during the
- branch shortening phase of the compiler.
-
- So instead we mark this jump as being special. This is
- far from ideal and knows that no code after this will
- muck around with the mode of the JUMP_INSN itself. */
- PUT_MODE (tmp, SImode);
- LABEL_NUSES (JUMP_LABEL (tmp))++;
- location = NEXT_INSN (location);
- }
-
- /* Emit a BARRIER after the jump. */
- emit_barrier_after (location);
- location = NEXT_INSN (location);
- }
-
- /* Emit marker for the end of the branch table. */
- emit_insn_before (gen_end_brtab (), location);
- location = NEXT_INSN (location);
- emit_barrier_after (location);
-
- /* Delete the ADDR_VEC or ADDR_DIFF_VEC. */
- delete_insn (insn);
- }
- }
- else
- {
- /* Sill need an end_brtab insn. */
- insns = get_insns ();
- for (insn = insns; insn; insn = NEXT_INSN (insn))
- {
- /* Find an ADDR_VEC insn. */
- if (GET_CODE (insn) != JUMP_INSN
- || (GET_CODE (PATTERN (insn)) != ADDR_VEC
- && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC))
- continue;
-
- /* Now generate markers for the beginning and end of the
- branch table. */
- emit_insn_before (gen_begin_brtab (), insn);
- emit_insn_after (gen_end_brtab (), insn);
- }
- }
-}
-
-/* The PA has a number of odd instructions which can perform multiple
- tasks at once. On first generation PA machines (PA1.0 and PA1.1)
- it may be profitable to combine two instructions into one instruction
- with two outputs. It's not profitable PA2.0 machines because the
- two outputs would take two slots in the reorder buffers.
-
- This routine finds instructions which can be combined and combines
- them. We only support some of the potential combinations, and we
- only try common ways to find suitable instructions.
-
- * addb can add two registers or a register and a small integer
- and jump to a nearby (+-8k) location. Normally the jump to the
- nearby location is conditional on the result of the add, but by
- using the "true" condition we can make the jump unconditional.
- Thus addb can perform two independent operations in one insn.
-
- * movb is similar to addb in that it can perform a reg->reg
- or small immediate->reg copy and jump to a nearby (+-8k location).
-
- * fmpyadd and fmpysub can perform a FP multiply and either an
- FP add or FP sub if the operands of the multiply and add/sub are
- independent (there are other minor restrictions). Note both
- the fmpy and fadd/fsub can in theory move to better spots according
- to data dependencies, but for now we require the fmpy stay at a
- fixed location.
-
- * Many of the memory operations can perform pre & post updates
- of index registers. GCC's pre/post increment/decrement addressing
- is far too simple to take advantage of all the possibilities. This
- pass may not be suitable since those insns may not be independent.
-
- * comclr can compare two ints or an int and a register, nullify
- the following instruction and zero some other register. This
- is more difficult to use as it's harder to find an insn which
- will generate a comclr than finding something like an unconditional
- branch. (conditional moves & long branches create comclr insns).
-
- * Most arithmetic operations can conditionally skip the next
- instruction. They can be viewed as "perform this operation
- and conditionally jump to this nearby location" (where nearby
- is an insns away). These are difficult to use due to the
- branch length restrictions. */
-
-static void
-pa_combine_instructions (insns)
- rtx insns ATTRIBUTE_UNUSED;
-{
- rtx anchor, new;
-
- /* This can get expensive since the basic algorithm is on the
- order of O(n^2) (or worse). Only do it for -O2 or higher
- levels of optimization. */
- if (optimize < 2)
- return;
-
- /* Walk down the list of insns looking for "anchor" insns which
- may be combined with "floating" insns. As the name implies,
- "anchor" instructions don't move, while "floating" insns may
- move around. */
- new = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, NULL_RTX, NULL_RTX));
- new = make_insn_raw (new);
-
- for (anchor = get_insns (); anchor; anchor = NEXT_INSN (anchor))
- {
- enum attr_pa_combine_type anchor_attr;
- enum attr_pa_combine_type floater_attr;
-
- /* We only care about INSNs, JUMP_INSNs, and CALL_INSNs.
- Also ignore any special USE insns. */
- if ((GET_CODE (anchor) != INSN
- && GET_CODE (anchor) != JUMP_INSN
- && GET_CODE (anchor) != CALL_INSN)
- || GET_CODE (PATTERN (anchor)) == USE
- || GET_CODE (PATTERN (anchor)) == CLOBBER
- || GET_CODE (PATTERN (anchor)) == ADDR_VEC
- || GET_CODE (PATTERN (anchor)) == ADDR_DIFF_VEC)
- continue;
-
- anchor_attr = get_attr_pa_combine_type (anchor);
- /* See if anchor is an insn suitable for combination. */
- if (anchor_attr == PA_COMBINE_TYPE_FMPY
- || anchor_attr == PA_COMBINE_TYPE_FADDSUB
- || (anchor_attr == PA_COMBINE_TYPE_UNCOND_BRANCH
- && ! forward_branch_p (anchor)))
- {
- rtx floater;
-
- for (floater = PREV_INSN (anchor);
- floater;
- floater = PREV_INSN (floater))
- {
- if (GET_CODE (floater) == NOTE
- || (GET_CODE (floater) == INSN
- && (GET_CODE (PATTERN (floater)) == USE
- || GET_CODE (PATTERN (floater)) == CLOBBER)))
- continue;
-
- /* Anything except a regular INSN will stop our search. */
- if (GET_CODE (floater) != INSN
- || GET_CODE (PATTERN (floater)) == ADDR_VEC
- || GET_CODE (PATTERN (floater)) == ADDR_DIFF_VEC)
- {
- floater = NULL_RTX;
- break;
- }
-
- /* See if FLOATER is suitable for combination with the
- anchor. */
- floater_attr = get_attr_pa_combine_type (floater);
- if ((anchor_attr == PA_COMBINE_TYPE_FMPY
- && floater_attr == PA_COMBINE_TYPE_FADDSUB)
- || (anchor_attr == PA_COMBINE_TYPE_FADDSUB
- && floater_attr == PA_COMBINE_TYPE_FMPY))
- {
- /* If ANCHOR and FLOATER can be combined, then we're
- done with this pass. */
- if (pa_can_combine_p (new, anchor, floater, 0,
- SET_DEST (PATTERN (floater)),
- XEXP (SET_SRC (PATTERN (floater)), 0),
- XEXP (SET_SRC (PATTERN (floater)), 1)))
- break;
- }
-
- else if (anchor_attr == PA_COMBINE_TYPE_UNCOND_BRANCH
- && floater_attr == PA_COMBINE_TYPE_ADDMOVE)
- {
- if (GET_CODE (SET_SRC (PATTERN (floater))) == PLUS)
- {
- if (pa_can_combine_p (new, anchor, floater, 0,
- SET_DEST (PATTERN (floater)),
- XEXP (SET_SRC (PATTERN (floater)), 0),
- XEXP (SET_SRC (PATTERN (floater)), 1)))
- break;
- }
- else
- {
- if (pa_can_combine_p (new, anchor, floater, 0,
- SET_DEST (PATTERN (floater)),
- SET_SRC (PATTERN (floater)),
- SET_SRC (PATTERN (floater))))
- break;
- }
- }
- }
-
- /* If we didn't find anything on the backwards scan try forwards. */
- if (!floater
- && (anchor_attr == PA_COMBINE_TYPE_FMPY
- || anchor_attr == PA_COMBINE_TYPE_FADDSUB))
- {
- for (floater = anchor; floater; floater = NEXT_INSN (floater))
- {
- if (GET_CODE (floater) == NOTE
- || (GET_CODE (floater) == INSN
- && (GET_CODE (PATTERN (floater)) == USE
- || GET_CODE (PATTERN (floater)) == CLOBBER)))
-
- continue;
-
- /* Anything except a regular INSN will stop our search. */
- if (GET_CODE (floater) != INSN
- || GET_CODE (PATTERN (floater)) == ADDR_VEC
- || GET_CODE (PATTERN (floater)) == ADDR_DIFF_VEC)
- {
- floater = NULL_RTX;
- break;
- }
-
- /* See if FLOATER is suitable for combination with the
- anchor. */
- floater_attr = get_attr_pa_combine_type (floater);
- if ((anchor_attr == PA_COMBINE_TYPE_FMPY
- && floater_attr == PA_COMBINE_TYPE_FADDSUB)
- || (anchor_attr == PA_COMBINE_TYPE_FADDSUB
- && floater_attr == PA_COMBINE_TYPE_FMPY))
- {
- /* If ANCHOR and FLOATER can be combined, then we're
- done with this pass. */
- if (pa_can_combine_p (new, anchor, floater, 1,
- SET_DEST (PATTERN (floater)),
- XEXP (SET_SRC (PATTERN(floater)),0),
- XEXP(SET_SRC(PATTERN(floater)),1)))
- break;
- }
- }
- }
-
- /* FLOATER will be nonzero if we found a suitable floating
- insn for combination with ANCHOR. */
- if (floater
- && (anchor_attr == PA_COMBINE_TYPE_FADDSUB
- || anchor_attr == PA_COMBINE_TYPE_FMPY))
- {
- /* Emit the new instruction and delete the old anchor. */
- emit_insn_before (gen_rtx_PARALLEL (VOIDmode,
- gen_rtvec (2,
- PATTERN (anchor),
- PATTERN (floater))),
- anchor);
- PUT_CODE (anchor, NOTE);
- NOTE_LINE_NUMBER (anchor) = NOTE_INSN_DELETED;
- NOTE_SOURCE_FILE (anchor) = 0;
-
- /* Emit a special USE insn for FLOATER, then delete
- the floating insn. */
- emit_insn_before (gen_rtx_USE (VOIDmode, floater), floater);
- delete_insn (floater);
-
- continue;
- }
- else if (floater
- && anchor_attr == PA_COMBINE_TYPE_UNCOND_BRANCH)
- {
- rtx temp;
- /* Emit the new_jump instruction and delete the old anchor. */
- temp = emit_jump_insn_before (gen_rtx_PARALLEL (VOIDmode,
- gen_rtvec (2, PATTERN (anchor),
- PATTERN (floater))),
- anchor);
- JUMP_LABEL (temp) = JUMP_LABEL (anchor);
- PUT_CODE (anchor, NOTE);
- NOTE_LINE_NUMBER (anchor) = NOTE_INSN_DELETED;
- NOTE_SOURCE_FILE (anchor) = 0;
-
- /* Emit a special USE insn for FLOATER, then delete
- the floating insn. */
- emit_insn_before (gen_rtx_USE (VOIDmode, floater), floater);
- delete_insn (floater);
- continue;
- }
- }
- }
-}
-
-int
-pa_can_combine_p (new, anchor, floater, reversed, dest, src1, src2)
- rtx new, anchor, floater;
- int reversed;
- rtx dest, src1, src2;
-{
- int insn_code_number;
- rtx start, end;
-
- /* Create a PARALLEL with the patterns of ANCHOR and
- FLOATER, try to recognize it, then test constraints
- for the resulting pattern.
-
- If the pattern doesn't match or the constraints
- aren't met keep searching for a suitable floater
- insn. */
- XVECEXP (PATTERN (new), 0, 0) = PATTERN (anchor);
- XVECEXP (PATTERN (new), 0, 1) = PATTERN (floater);
- INSN_CODE (new) = -1;
- insn_code_number = recog_memoized (new);
- if (insn_code_number < 0
- || !constrain_operands (insn_code_number, 1))
- return 0;
-
- if (reversed)
- {
- start = anchor;
- end = floater;
- }
- else
- {
- start = floater;
- end = anchor;
- }
-
- /* There's up to three operands to consider. One
- output and two inputs.
-
- The output must not be used between FLOATER & ANCHOR
- exclusive. The inputs must not be set between
- FLOATER and ANCHOR exclusive. */
-
- if (reg_used_between_p (dest, start, end))
- return 0;
-
- if (reg_set_between_p (src1, start, end))
- return 0;
-
- if (reg_set_between_p (src2, start, end))
- return 0;
-
- /* If we get here, then everything is good. */
- return 1;
-}
-
-/* Return nonzero if sets and references for INSN are delayed.
-
- Millicode insns are actually function calls with some special
- constraints on arguments and register usage.
-
- Millicode calls always expect their arguments in the integer argument
- registers, and always return their result in %r29 (ret1). They
- are expected to clobber their arguments, %r1, %r29, and %r31 and
- nothing else.
-
- By considering this effects delayed reorg reorg can put insns
- which set the argument registers into the delay slot of the millicode
- call -- thus they act more like traditional CALL_INSNs.
-
- get_attr_type will try to recognize the given insn, so make sure to
- filter out things it will not accept -- SEQUENCE, USE and CLOBBER insns
- in particular. */
-int
-insn_sets_and_refs_are_delayed (insn)
- rtx insn;
-{
- return ((GET_CODE (insn) == INSN
- && GET_CODE (PATTERN (insn)) != SEQUENCE
- && GET_CODE (PATTERN (insn)) != USE
- && GET_CODE (PATTERN (insn)) != CLOBBER
- && get_attr_type (insn) == TYPE_MILLI));
-}
diff --git a/gcc/config/pa/pa.h b/gcc/config/pa/pa.h
deleted file mode 100755
index a63d955..0000000
--- a/gcc/config/pa/pa.h
+++ /dev/null
@@ -1,2601 +0,0 @@
-/* Definitions of target machine for GNU compiler, for the HP Spectrum.
- Copyright (C) 1992, 93-98, 1999 Free Software Foundation, Inc.
- Contributed by Michael Tiemann (tiemann@cygnus.com) of Cygnus Support
- and Tim Moore (moore@defmacro.cs.utah.edu) of the Center for
- Software Science at the University of Utah.
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 1, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-enum cmp_type /* comparison type */
-{
- CMP_SI, /* compare integers */
- CMP_SF, /* compare single precision floats */
- CMP_DF, /* compare double precision floats */
- CMP_MAX /* max comparison type */
-};
-
-/* For long call handling. */
-extern unsigned int total_code_bytes;
-
-/* Which processor to schedule for. */
-
-enum processor_type
-{
- PROCESSOR_700,
- PROCESSOR_7100,
- PROCESSOR_7100LC,
- PROCESSOR_7200,
- /* CYGNUS LOCAL PA8000/law */
- PROCESSOR_8000
- /* END CYGNUS LCOAL */
-};
-
-/* For -mschedule= option. */
-extern char *pa_cpu_string;
-extern enum processor_type pa_cpu;
-
-#define pa_cpu_attr ((enum attr_cpu)pa_cpu)
-
-/* CYGNUS LOCAL PA8000/law */
-/* The 700 can only issue a single insn at a time.
- The 7XXX processors can issue two insns at a time. */
-#define ISSUE_RATE \
- (pa_cpu == PROCESSOR_700 ? 1 : pa_cpu == PROCESSOR_8000 ? 4 : 2)
-/* END CYGNUS LOCAL */
-
-/* Print subsidiary information on the compiler version in use. */
-
-#define TARGET_VERSION fputs (" (hppa)", stderr);
-
-/* Run-time compilation parameters selecting different hardware subsets. */
-
-extern int target_flags;
-
-/* compile code for HP-PA 1.1 ("Snake") */
-
-#define TARGET_SNAKE (target_flags & 1)
-
-/* Disable all FP registers (they all become fixed). This may be necessary
- for compiling kernels which perform lazy context switching of FP regs.
- Note if you use this option and try to perform floating point operations
- the compiler will abort! */
-
-#define TARGET_DISABLE_FPREGS (target_flags & 2)
-
-/* Generate code which assumes that calls through function pointers will
- never cross a space boundary. Such assumptions are generally safe for
- building kernels and statically linked executables. Code compiled with
- this option will fail miserably if the executable is dynamically linked
- or uses nested functions!
-
- This is also used to trigger aggressive unscaled index addressing. */
-#define TARGET_NO_SPACE_REGS (target_flags & 4)
-
-/* Allow unconditional jumps in the delay slots of call instructions. */
-#define TARGET_JUMP_IN_DELAY (target_flags & 8)
-
-/* Optimize for space. Currently this only turns on out of line
- prologues and epilogues. */
-#define TARGET_SPACE (target_flags & 16)
-
-/* Disable indexed addressing modes. */
-
-#define TARGET_DISABLE_INDEXING (target_flags & 32)
-
-/* Emit code which follows the new portable runtime calling conventions
- HP wants everyone to use for ELF objects. If at all possible you want
- to avoid this since it's a performance loss for non-prototyped code.
-
- Note TARGET_PORTABLE_RUNTIME also forces all calls to use inline
- long-call stubs which is quite expensive. */
-
-#define TARGET_PORTABLE_RUNTIME (target_flags & 64)
-
-/* Emit directives only understood by GAS. This allows parameter
- relocations to work for static functions. There is no way
- to make them work the HP assembler at this time. */
-
-#define TARGET_GAS (target_flags & 128)
-
-/* Emit code for processors which do not have an FPU. */
-
-#define TARGET_SOFT_FLOAT (target_flags & 256)
-
-/* Use 3-insn load/store sequences for access to large data segments
- in shared libraries on hpux10. */
-#define TARGET_LONG_LOAD_STORE (target_flags & 512)
-
-/* Use a faster sequence for indirect calls. */
-#define TARGET_FAST_INDIRECT_CALLS (target_flags & 1024)
-
-/* Generate code with big switch statements to avoid out of range branches
- occurring within the switch table. */
-#define TARGET_BIG_SWITCH (target_flags & 2048)
-
-/* CYGNUS LOCAL pa8000/law */
-/* Generate PA2.0 instructions. */
-#define TARGET_PARISC_2_0 (target_flags & 4096)
-/* END CYGNUS LOCAL */
-
-/* Macro to define tables used to set the flags.
- This is a list in braces of pairs in braces,
- each pair being { "NAME", VALUE }
- where VALUE is the bits to set or minus the bits to clear.
- An empty string NAME is used to identify the default VALUE. */
-
-#define TARGET_SWITCHES \
- {{"snake", 1}, \
- {"nosnake", -1}, \
- {"pa-risc-1-0", -1}, \
- {"pa-risc-1-1", 1}, \
- {"disable-fpregs", 2}, \
- {"no-disable-fpregs", -2}, \
- {"no-space-regs", 4}, \
- {"space-regs", -4}, \
- {"jump-in-delay", 8}, \
- {"no-jump-in-delay", -8}, \
- {"space", 16}, \
- {"no-space", -16}, \
- {"disable-indexing", 32}, \
- {"no-disable-indexing", -32},\
- {"portable-runtime", 64}, \
- {"no-portable-runtime", -64},\
- {"gas", 128}, \
- {"no-gas", -128}, \
- {"soft-float", 256}, \
- {"no-soft-float", -256}, \
- {"long-load-store", 512}, \
- {"no-long-load-store", -512},\
- {"fast-indirect-calls", 1024},\
- {"no-fast-indirect-calls", -1024},\
- {"big-switch", 2048}, \
- {"no-big-switch", -2048}, \
- /* CYGNUS LOCAL pa8000/law */\
- {"pa-risc-2-0", 4097}, \
- {"no-pa-risc-2-0", -4096}, \
- /* END CYGNUS LOCAL */ \
- {"linker-opt", 0}, \
- { "", TARGET_DEFAULT | TARGET_CPU_DEFAULT}}
-
-#ifndef TARGET_DEFAULT
-#define TARGET_DEFAULT 0x88 /* TARGET_GAS + TARGET_JUMP_IN_DELAY */
-#endif
-
-#ifndef TARGET_CPU_DEFAULT
-#define TARGET_CPU_DEFAULT 0
-#endif
-
-#define TARGET_OPTIONS \
-{ \
- { "schedule=", &pa_cpu_string }\
-}
-
-#define OVERRIDE_OPTIONS override_options ()
-
-#define DBX_DEBUGGING_INFO
-#define DEFAULT_GDB_EXTENSIONS 1
-
-/* This is the way other stabs-in-XXX tools do things. We will be
- compatible. */
-#define DBX_BLOCKS_FUNCTION_RELATIVE 1
-
-/* Likewise for linenos.
-
- We make the first line stab special to avoid adding several
- gross hacks to GAS. */
-#undef ASM_OUTPUT_SOURCE_LINE
-#define ASM_OUTPUT_SOURCE_LINE(file, line) \
- { static int sym_lineno = 1; \
- static tree last_function_decl = NULL; \
- if (current_function_decl == last_function_decl) \
- fprintf (file, "\t.stabn 68,0,%d,L$M%d-%s\nL$M%d:\n", \
- line, sym_lineno, \
- XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0) + 1, \
- sym_lineno); \
- else \
- fprintf (file, "\t.stabn 68,0,%d,0\n", line); \
- last_function_decl = current_function_decl; \
- sym_lineno += 1; }
-
-/* But, to make this work, we have to output the stabs for the function
- name *first*... */
-#define DBX_FUNCTION_FIRST
-
-/* Only labels should ever begin in column zero. */
-#define ASM_STABS_OP "\t.stabs"
-#define ASM_STABN_OP "\t.stabn"
-
-/* GDB always assumes the current function's frame begins at the value
- of the stack pointer upon entry to the current function. Accessing
- local variables and parameters passed on the stack is done using the
- base of the frame + an offset provided by GCC.
-
- For functions which have frame pointers this method works fine;
- the (frame pointer) == (stack pointer at function entry) and GCC provides
- an offset relative to the frame pointer.
-
- This loses for functions without a frame pointer; GCC provides an offset
- which is relative to the stack pointer after adjusting for the function's
- frame size. GDB would prefer the offset to be relative to the value of
- the stack pointer at the function's entry. Yuk! */
-#define DEBUGGER_AUTO_OFFSET(X) \
- ((GET_CODE (X) == PLUS ? INTVAL (XEXP (X, 1)) : 0) \
- + (frame_pointer_needed ? 0 : compute_frame_size (get_frame_size (), 0)))
-
-#define DEBUGGER_ARG_OFFSET(OFFSET, X) \
- ((GET_CODE (X) == PLUS ? OFFSET : 0) \
- + (frame_pointer_needed ? 0 : compute_frame_size (get_frame_size (), 0)))
-
-/* gdb needs a null N_SO at the end of each file for scattered loading. */
-
-#undef DBX_OUTPUT_MAIN_SOURCE_FILE_END
-#define DBX_OUTPUT_MAIN_SOURCE_FILE_END(FILE, FILENAME) \
- text_section (); \
- if (!TARGET_PORTABLE_RUNTIME) \
- fputs ("\t.SPACE $TEXT$\n\t.NSUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY\n", FILE); \
- else \
- fprintf (FILE, "%s\n", TEXT_SECTION_ASM_OP); \
- fprintf (FILE, \
- "\t.stabs \"\",%d,0,0,L$text_end0000\nL$text_end0000:\n", N_SO)
-
-/* CYGNUS LOCAL hpux11/law */
-#if ((TARGET_DEFAULT | TARGET_CPU_DEFAULT) & 1) == 0
-#define CPP_SPEC "%{msnake:-D__hp9000s700 -D_PA_RISC1_1}\
- %{mpa-risc-1-1:-D__hp9000s700 -D_PA_RISC1_1}\
- %{!ansi: -D_HPUX_SOURCE -D_HIUX_SOURCE -D__STDC_EXT__}\
- %{threads:-D_REENTRANT -D_DCE_THREADS}"
-#else
-#define CPP_SPEC "%{!mpa-risc-1-0:%{!mnosnake:%{!msoft-float:-D__hp9000s700 -D_PA_RISC1_1}}} \
- %{!ansi: -D_HPUX_SOURCE -D_HIUX_SOURCE -D__STDC_EXT__}\
- %{threads:-D_REENTRANT -D_DCE_THREADS}"
-#endif
-/* END CYGNUS LOCAL */
-
-/* Defines for a K&R CC */
-
-#define CC1_SPEC "%{pg:} %{p:}"
-
-#define LINK_SPEC "%{mlinker-opt:-O} %{!shared:-u main} %{shared:-b}"
-
-/* We don't want -lg. */
-#ifndef LIB_SPEC
-#define LIB_SPEC "%{!p:%{!pg:-lc}}%{p:-lc_p}%{pg:-lc_p}"
-#endif
-
-/* Make gcc agree with <machine/ansi.h> */
-
-#define SIZE_TYPE "unsigned int"
-#define PTRDIFF_TYPE "int"
-#define WCHAR_TYPE "unsigned int"
-#define WCHAR_TYPE_SIZE 32
-
-/* Show we can debug even without a frame pointer. */
-#define CAN_DEBUG_WITHOUT_FP
-
-/* Machine dependent reorg pass. */
-#define MACHINE_DEPENDENT_REORG(X) pa_reorg(X)
-
-/* Prototype function used in MACHINE_DEPENDENT_REORG macro. */
-void pa_reorg ();
-
-/* Prototype function used in various macros. */
-int symbolic_operand ();
-
-/* Used in insn-*.c. */
-int following_call ();
-int function_label_operand ();
-int lhs_lshift_cint_operand ();
-
-/* Names to predefine in the preprocessor for this target machine. */
-
-#define CPP_PREDEFINES "-Dhppa -Dhp9000s800 -D__hp9000s800 -Dhp9k8 -Dunix -Dhp9000 -Dhp800 -Dspectrum -DREVARGV -Asystem(unix) -Asystem(bsd) -Acpu(hppa) -Amachine(hppa)"
-
-/* HPUX has a program 'chatr' to list the dependencies of dynamically
- linked executables and shared libraries. */
-#define LDD_SUFFIX "chatr"
-/* Look for lines like "dynamic /usr/lib/X11R5/libX11.sl"
- or "static /usr/lib/X11R5/libX11.sl".
-
- HPUX 10.20 also has lines like "static branch prediction ..."
- so we filter that out explicitly.
-
- We also try to bound our search for libraries with marker
- lines. What a pain. */
-#define PARSE_LDD_OUTPUT(PTR) \
-do { \
- static int in_shlib_list = 0; \
- while (*PTR == ' ') PTR++; \
- if (strncmp (PTR, "shared library list:", \
- sizeof ("shared library list:") - 1) == 0) \
- { \
- PTR = 0; \
- in_shlib_list = 1; \
- } \
- else if (strncmp (PTR, "shared library binding:", \
- sizeof ("shared library binding:") - 1) == 0)\
- { \
- PTR = 0; \
- in_shlib_list = 0; \
- } \
- else if (strncmp (PTR, "static branch prediction disabled", \
- sizeof ("static branch prediction disabled") - 1) == 0)\
- { \
- PTR = 0; \
- in_shlib_list = 0; \
- } \
- else if (in_shlib_list \
- && strncmp (PTR, "dynamic", sizeof ("dynamic") - 1) == 0) \
- { \
- PTR += sizeof ("dynamic") - 1; \
- while (*p == ' ') PTR++; \
- } \
- else if (in_shlib_list \
- && strncmp (PTR, "static", sizeof ("static") - 1) == 0) \
- { \
- PTR += sizeof ("static") - 1; \
- while (*p == ' ') PTR++; \
- } \
- else \
- PTR = 0; \
-} while (0)
-
-/* target machine storage layout */
-
-/* Define for cross-compilation from a host with a different float format
- or endianness (e.g. VAX, x86). */
-#define REAL_ARITHMETIC
-
-/* Define this macro if it is advisable to hold scalars in registers
- in a wider mode than that declared by the program. In such cases,
- the value is constrained to be within the bounds of the declared
- type, but kept valid in the wider mode. The signedness of the
- extension may differ from that of the type. */
-
-#define PROMOTE_MODE(MODE,UNSIGNEDP,TYPE) \
- if (GET_MODE_CLASS (MODE) == MODE_INT \
- && GET_MODE_SIZE (MODE) < 4) \
- (MODE) = SImode;
-
-/* Define this if most significant bit is lowest numbered
- in instructions that operate on numbered bit-fields. */
-#define BITS_BIG_ENDIAN 1
-
-/* Define this if most significant byte of a word is the lowest numbered. */
-/* That is true on the HP-PA. */
-#define BYTES_BIG_ENDIAN 1
-
-/* Define this if most significant word of a multiword number is lowest
- numbered. */
-#define WORDS_BIG_ENDIAN 1
-
-/* number of bits in an addressable storage unit */
-#define BITS_PER_UNIT 8
-
-/* Width in bits of a "word", which is the contents of a machine register.
- Note that this is not necessarily the width of data type `int';
- if using 16-bit ints on a 68000, this would still be 32.
- But on a machine with 16-bit registers, this would be 16. */
-#define BITS_PER_WORD 32
-
-/* Width of a word, in units (bytes). */
-#define UNITS_PER_WORD 4
-
-/* Width in bits of a pointer.
- See also the macro `Pmode' defined below. */
-#define POINTER_SIZE 32
-
-/* Allocation boundary (in *bits*) for storing arguments in argument list. */
-#define PARM_BOUNDARY 32
-
-/* Largest alignment required for any stack parameter, in bits.
- Don't define this if it is equal to PARM_BOUNDARY */
-#define MAX_PARM_BOUNDARY 64
-
-/* Boundary (in *bits*) on which stack pointer is always aligned;
- certain optimizations in combine depend on this.
-
- GCC for the PA always rounds its stacks to a 512bit boundary,
- but that happens late in the compilation process. */
-#define STACK_BOUNDARY 64
-
-/* Allocation boundary (in *bits*) for the code of a function. */
-#define FUNCTION_BOUNDARY 32
-
-/* Alignment of field after `int : 0' in a structure. */
-#define EMPTY_FIELD_BOUNDARY 32
-
-/* Every structure's size must be a multiple of this. */
-#define STRUCTURE_SIZE_BOUNDARY 8
-
-/* A bitfield declared as `int' forces `int' alignment for the struct. */
-#define PCC_BITFIELD_TYPE_MATTERS 1
-
-/* No data type wants to be aligned rounder than this. */
-#define BIGGEST_ALIGNMENT 64
-
-/* The .align directive in the HP assembler allows up to a 32 alignment. */
-#define MAX_OFILE_ALIGNMENT 32768
-
-/* Get around hp-ux assembler bug, and make strcpy of constants fast. */
-#define CONSTANT_ALIGNMENT(CODE, TYPEALIGN) \
- ((TYPEALIGN) < 32 ? 32 : (TYPEALIGN))
-
-/* Make arrays of chars word-aligned for the same reasons. */
-#define DATA_ALIGNMENT(TYPE, ALIGN) \
- (TREE_CODE (TYPE) == ARRAY_TYPE \
- && TYPE_MODE (TREE_TYPE (TYPE)) == QImode \
- && (ALIGN) < BITS_PER_WORD ? BITS_PER_WORD : (ALIGN))
-
-
-/* Set this nonzero if move instructions will actually fail to work
- when given unaligned data. */
-#define STRICT_ALIGNMENT 1
-
-/* Generate calls to memcpy, memcmp and memset. */
-#define TARGET_MEM_FUNCTIONS
-
-/* Standard register usage. */
-
-/* Number of actual hardware registers.
- The hardware registers are assigned numbers for the compiler
- from 0 to just below FIRST_PSEUDO_REGISTER.
- All registers that the compiler knows about must be given numbers,
- even those that are not normally considered general registers.
-
- HP-PA 1.0 has 32 fullword registers and 16 floating point
- registers. The floating point registers hold either word or double
- word values.
-
- 16 additional registers are reserved.
-
- HP-PA 1.1 has 32 fullword registers and 32 floating point
- registers. However, the floating point registers behave
- differently: the left and right halves of registers are addressable
- as 32 bit registers. So, we will set things up like the 68k which
- has different fp units: define separate register sets for the 1.0
- and 1.1 fp units. */
-
-#define FIRST_PSEUDO_REGISTER 89 /* 32 general regs + 56 fp regs +
- + 1 shift reg */
-
-/* 1 for registers that have pervasive standard uses
- and are not available for the register allocator.
-
- On the HP-PA, these are:
- Reg 0 = 0 (hardware). However, 0 is used for condition code,
- so is not fixed.
- Reg 1 = ADDIL target/Temporary (hardware).
- Reg 2 = Return Pointer
- Reg 3 = Frame Pointer
- Reg 4 = Frame Pointer (>8k varying frame with HP compilers only)
- Reg 4-18 = Preserved Registers
- Reg 19 = Linkage Table Register in HPUX 8.0 shared library scheme.
- Reg 20-22 = Temporary Registers
- Reg 23-26 = Temporary/Parameter Registers
- Reg 27 = Global Data Pointer (hp)
- Reg 28 = Temporary/???/Return Value register
- Reg 29 = Temporary/Static Chain/Return Value register #2
- Reg 30 = stack pointer
- Reg 31 = Temporary/Millicode Return Pointer (hp)
-
- Freg 0-3 = Status Registers -- Not known to the compiler.
- Freg 4-7 = Arguments/Return Value
- Freg 8-11 = Temporary Registers
- Freg 12-15 = Preserved Registers
-
- Freg 16-31 = Reserved
-
- On the Snake, fp regs are
-
- Freg 0-3 = Status Registers -- Not known to the compiler.
- Freg 4L-7R = Arguments/Return Value
- Freg 8L-11R = Temporary Registers
- Freg 12L-21R = Preserved Registers
- Freg 22L-31R = Temporary Registers
-
-*/
-
-#define FIXED_REGISTERS \
- {0, 0, 0, 0, 0, 0, 0, 0, \
- 0, 0, 0, 0, 0, 0, 0, 0, \
- 0, 0, 0, 0, 0, 0, 0, 0, \
- 0, 0, 0, 1, 0, 0, 1, 0, \
- /* fp registers */ \
- 0, 0, 0, 0, 0, 0, 0, 0, \
- 0, 0, 0, 0, 0, 0, 0, 0, \
- 0, 0, 0, 0, 0, 0, 0, 0, \
- 0, 0, 0, 0, 0, 0, 0, 0, \
- 0, 0, 0, 0, 0, 0, 0, 0, \
- 0, 0, 0, 0, 0, 0, 0, 0, \
- 0, 0, 0, 0, 0, 0, 0, 0, \
- 0}
-
-/* 1 for registers not available across function calls.
- These must include the FIXED_REGISTERS and also any
- registers that can be used without being saved.
- The latter must include the registers where values are returned
- and the register where structure-value addresses are passed.
- Aside from that, you can include as many other registers as you like. */
-#define CALL_USED_REGISTERS \
- {1, 1, 1, 0, 0, 0, 0, 0, \
- 0, 0, 0, 0, 0, 0, 0, 0, \
- 0, 0, 0, 1, 1, 1, 1, 1, \
- 1, 1, 1, 1, 1, 1, 1, 1, \
- /* fp registers */ \
- 1, 1, 1, 1, 1, 1, 1, 1, \
- 1, 1, 1, 1, 1, 1, 1, 1, \
- 0, 0, 0, 0, 0, 0, 0, 0, \
- 0, 0, 0, 0, 0, 0, 0, 0, \
- 0, 0, 0, 0, 1, 1, 1, 1, \
- 1, 1, 1, 1, 1, 1, 1, 1, \
- 1, 1, 1, 1, 1, 1, 1, 1, \
- 1}
-
-#define CONDITIONAL_REGISTER_USAGE \
-{ \
- if (!TARGET_SNAKE) \
- { \
- for (i = 56; i < 88; i++) \
- fixed_regs[i] = call_used_regs[i] = 1; \
- for (i = 33; i < 88; i += 2) \
- fixed_regs[i] = call_used_regs[i] = 1; \
- } \
- if (TARGET_DISABLE_FPREGS || TARGET_SOFT_FLOAT)\
- { \
- for (i = 32; i < 88; i++) \
- fixed_regs[i] = call_used_regs[i] = 1; \
- } \
- if (flag_pic) \
- { \
- fixed_regs[PIC_OFFSET_TABLE_REGNUM] = 1; \
- fixed_regs[PIC_OFFSET_TABLE_REGNUM_SAVED] = 1;\
- } \
-}
-
-/* CYGNUS LOCAL PA8000/law */
-/* Allocate the call used registers first. This should minimize
- the number of registers that need to be saved (as call used
- registers will generally not be allocated across a call).
-
- Experimentation has shown slightly better results by allocating
- FP registers first.
-
- The PA8000 triggers a depedency stall if we use both halves of a
- floating point register in the same bundle. So we separate out the
- halves to discourage using them in nearby insns. This should be
- fixed in the register allocator/scheduler. */
-
-#define REG_ALLOC_ORDER \
- { \
- /* caller-saved fp regs. */ \
- 68, 70, 72, 74, 76, 78, 80, 82, \
- 84, 86, 40, 42, 44, 46, 32, 34, \
- 36, 38, \
- 69, 71, 73, 75, 77, 79, 81, 83, \
- 85, 87, 41, 43, 45, 47, 33, 35, \
- 37, 39, \
- /* caller-saved general regs. */ \
- 19, 20, 21, 22, 23, 24, 25, 26, \
- 27, 28, 29, 31, 2, \
- /* callee-saved fp regs. */ \
- 48, 50, 52, 54, 56, 58, 60, 62, \
- 64, 66, \
- 49, 51, 53, 55, 57, 59, 61, 63, \
- 65, 67, \
- /* callee-saved general regs. */ \
- 3, 4, 5, 6, 7, 8, 9, 10, \
- 11, 12, 13, 14, 15, 16, 17, 18, \
- /* special registers. */ \
- 1, 30, 0, 88}
-/* END CYGNUS LOCAL */
-
-
-/* True if register is floating-point. */
-#define FP_REGNO_P(N) ((N) >= 32 && (N) <= 87)
-
-/* Return number of consecutive hard regs needed starting at reg REGNO
- to hold something of mode MODE.
- This is ordinarily the length in words of a value of mode MODE
- but can be less for certain modes in special long registers.
-
- On the HP-PA, ordinary registers hold 32 bits worth;
- The floating point registers are 64 bits wide. Snake fp regs are 32
- bits wide */
-#define HARD_REGNO_NREGS(REGNO, MODE) \
- (!TARGET_SNAKE && FP_REGNO_P (REGNO) ? 1 \
- : ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
-
-/* Value is 1 if hard register REGNO can hold a value of machine-mode MODE.
- On the HP-PA, the cpu registers can hold any mode. We
- force this to be an even register is it cannot hold the full mode. */
-#define HARD_REGNO_MODE_OK(REGNO, MODE) \
- ((REGNO) == 0 ? (MODE) == CCmode || (MODE) == CCFPmode \
- /* On 1.0 machines, don't allow wide non-fp modes in fp regs. */ \
- : !TARGET_SNAKE && FP_REGNO_P (REGNO) \
- ? GET_MODE_SIZE (MODE) <= 4 || GET_MODE_CLASS (MODE) == MODE_FLOAT \
- /* Make wide modes be in aligned registers. */ \
- : GET_MODE_SIZE (MODE) <= 4 || ((REGNO) & 1) == 0)
-
-/* Value is 1 if it is a good idea to tie two pseudo registers
- when one has mode MODE1 and one has mode MODE2.
- If HARD_REGNO_MODE_OK could produce different values for MODE1 and MODE2,
- for any hard reg, then this must be 0 for correct output. */
-#define MODES_TIEABLE_P(MODE1, MODE2) \
- (GET_MODE_CLASS (MODE1) == GET_MODE_CLASS (MODE2))
-
-/* Specify the registers used for certain standard purposes.
- The values of these macros are register numbers. */
-
-/* The HP-PA pc isn't overloaded on a register that the compiler knows about. */
-/* #define PC_REGNUM */
-
-/* Register to use for pushing function arguments. */
-#define STACK_POINTER_REGNUM 30
-
-/* Base register for access to local variables of the function. */
-#define FRAME_POINTER_REGNUM 3
-
-/* Value should be nonzero if functions must have frame pointers. */
-#define FRAME_POINTER_REQUIRED \
- (current_function_calls_alloca)
-
-/* C statement to store the difference between the frame pointer
- and the stack pointer values immediately after the function prologue.
-
- Note, we always pretend that this is a leaf function because if
- it's not, there's no point in trying to eliminate the
- frame pointer. If it is a leaf function, we guessed right! */
-#define INITIAL_FRAME_POINTER_OFFSET(VAR) \
- do {(VAR) = - compute_frame_size (get_frame_size (), 0);} while (0)
-
-/* Base register for access to arguments of the function. */
-#define ARG_POINTER_REGNUM 3
-
-/* Register in which static-chain is passed to a function. */
-/* ??? */
-#define STATIC_CHAIN_REGNUM 29
-
-/* Register which holds offset table for position-independent
- data references. */
-
-#define PIC_OFFSET_TABLE_REGNUM 19
-#define PIC_OFFSET_TABLE_REG_CALL_CLOBBERED 1
-
-/* Register into which we save the PIC_OFFEST_TABLE_REGNUM so that it
- can be restore across function calls. */
-#define PIC_OFFSET_TABLE_REGNUM_SAVED 4
-
-/* SOM ABI says that objects larger than 64 bits are returned in memory. */
-#define DEFAULT_PCC_STRUCT_RETURN 0
-#define RETURN_IN_MEMORY(TYPE) \
- (int_size_in_bytes (TYPE) > 8)
-
-/* Register in which address to store a structure value
- is passed to a function. */
-#define STRUCT_VALUE_REGNUM 28
-
-/* Define the classes of registers for register constraints in the
- machine description. Also define ranges of constants.
-
- One of the classes must always be named ALL_REGS and include all hard regs.
- If there is more than one class, another class must be named NO_REGS
- and contain no registers.
-
- The name GENERAL_REGS must be the name of a class (or an alias for
- another name such as ALL_REGS). This is the class of registers
- that is allowed by "g" or "r" in a register constraint.
- Also, registers outside this class are allocated only when
- instructions express preferences for them.
-
- The classes must be numbered in nondecreasing order; that is,
- a larger-numbered class must never be contained completely
- in a smaller-numbered class.
-
- For any two classes, it is very desirable that there be another
- class that represents their union. */
-
- /* The HP-PA has four kinds of registers: general regs, 1.0 fp regs,
- 1.1 fp regs, and the high 1.1 fp regs, to which the operands of
- fmpyadd and fmpysub are restricted. */
-
-enum reg_class { NO_REGS, R1_REGS, GENERAL_REGS, FPUPPER_REGS, FP_REGS, GENERAL_OR_FP_REGS,
- SHIFT_REGS, ALL_REGS, LIM_REG_CLASSES};
-
-#define N_REG_CLASSES (int) LIM_REG_CLASSES
-
-/* Give names of register classes as strings for dump file. */
-
-#define REG_CLASS_NAMES \
- {"NO_REGS", "R1_REGS", "GENERAL_REGS", "FPUPPER_REGS", "FP_REGS", \
- "GENERAL_OR_FP_REGS", "SHIFT_REGS", "ALL_REGS"}
-
-/* Define which registers fit in which classes.
- This is an initializer for a vector of HARD_REG_SET
- of length N_REG_CLASSES. Register 0, the "condition code" register,
- is in no class. */
-
-#define REG_CLASS_CONTENTS \
- {{0x00000000, 0x00000000, 0x00000000}, /* NO_REGS */ \
- {0x00000002, 0x00000000, 0x00000000}, /* R1_REGS */ \
- {0xfffffffe, 0x00000000, 0x00000000}, /* GENERAL_REGS */ \
- {0x00000000, 0xff000000, 0x00ffffff}, /* FPUPPER_REGS */ \
- {0x00000000, 0xffffffff, 0x00ffffff}, /* FP_REGS */ \
- {0xfffffffe, 0xffffffff, 0x00ffffff}, /* GENERAL_OR_FP_REGS */ \
- {0x00000000, 0x00000000, 0x01000000}, /* SHIFT_REGS */ \
- {0xfffffffe, 0xffffffff, 0x01ffffff}} /* ALL_REGS */
-
-/* The same information, inverted:
- Return the class number of the smallest class containing
- reg number REGNO. This could be a conditional expression
- or could index an array. */
-
-#define REGNO_REG_CLASS(REGNO) \
- ((REGNO) == 0 ? NO_REGS \
- : (REGNO) == 1 ? R1_REGS \
- : (REGNO) < 32 ? GENERAL_REGS \
- : (REGNO) < 56 ? FP_REGS \
- : (REGNO) < 88 ? FPUPPER_REGS \
- : SHIFT_REGS)
-
-/* The class value for index registers, and the one for base regs. */
-#define INDEX_REG_CLASS GENERAL_REGS
-#define BASE_REG_CLASS GENERAL_REGS
-
-#define FP_REG_CLASS_P(CLASS) \
- ((CLASS) == FP_REGS || (CLASS) == FPUPPER_REGS)
-
-/* Get reg_class from a letter such as appears in the machine description. */
-/* Keep 'x' for backward compatibility with user asm. */
-#define REG_CLASS_FROM_LETTER(C) \
- ((C) == 'f' ? FP_REGS : \
- (C) == 'y' ? FPUPPER_REGS : \
- (C) == 'x' ? FP_REGS : \
- (C) == 'q' ? SHIFT_REGS : \
- (C) == 'a' ? R1_REGS : \
- (C) == 'Z' ? ALL_REGS : NO_REGS)
-
-/* The letters I, J, K, L and M in a register constraint string
- can be used to stand for particular ranges of immediate operands.
- This macro defines what the ranges are.
- C is the letter, and VALUE is a constant value.
- Return 1 if VALUE is in the range specified by C.
-
- `I' is used for the 11 bit constants.
- `J' is used for the 14 bit constants.
- `K' is used for values that can be moved with a zdepi insn.
- `L' is used for the 5 bit constants.
- `M' is used for 0.
- `N' is used for values with the least significant 11 bits equal to zero.
- `O' is used for numbers n such that n+1 is a power of 2.
- */
-
-#define CONST_OK_FOR_LETTER_P(VALUE, C) \
- ((C) == 'I' ? VAL_11_BITS_P (VALUE) \
- : (C) == 'J' ? VAL_14_BITS_P (VALUE) \
- : (C) == 'K' ? zdepi_cint_p (VALUE) \
- : (C) == 'L' ? VAL_5_BITS_P (VALUE) \
- : (C) == 'M' ? (VALUE) == 0 \
- : (C) == 'N' ? ((VALUE) & 0x7ff) == 0 \
- : (C) == 'O' ? (((VALUE) & ((VALUE) + 1)) == 0) \
- : (C) == 'P' ? and_mask_p (VALUE) \
- : 0)
-
-/* Prototype function used in macro CONST_OK_FOR_LETTER_P. */
-int zdepi_cint_p ();
-
-/* Similar, but for floating or large integer constants, and defining letters
- G and H. Here VALUE is the CONST_DOUBLE rtx itself.
-
- For PA, `G' is the floating-point constant zero. `H' is undefined. */
-
-#define CONST_DOUBLE_OK_FOR_LETTER_P(VALUE, C) \
- ((C) == 'G' ? (GET_MODE_CLASS (GET_MODE (VALUE)) == MODE_FLOAT \
- && (VALUE) == CONST0_RTX (GET_MODE (VALUE))) \
- : 0)
-
-/* Given an rtx X being reloaded into a reg required to be
- in class CLASS, return the class of reg to actually use.
- In general this is just CLASS; but on some machines
- in some cases it is preferable to use a more restrictive class. */
-#define PREFERRED_RELOAD_CLASS(X,CLASS) (CLASS)
-
-/* Return the register class of a scratch register needed to copy IN into
- or out of a register in CLASS in MODE. If it can be done directly
- NO_REGS is returned.
-
- Avoid doing any work for the common case calls. */
-
-#define SECONDARY_RELOAD_CLASS(CLASS,MODE,IN) \
- ((CLASS == BASE_REG_CLASS && GET_CODE (IN) == REG \
- && REGNO (IN) < FIRST_PSEUDO_REGISTER) \
- ? NO_REGS : secondary_reload_class (CLASS, MODE, IN))
-
-/* On the PA it is not possible to directly move data between
- GENERAL_REGS and FP_REGS. */
-#define SECONDARY_MEMORY_NEEDED(CLASS1, CLASS2, MODE) \
- (FP_REG_CLASS_P (CLASS1) != FP_REG_CLASS_P (CLASS2))
-
-/* Return the stack location to use for secondary memory needed reloads. */
-#define SECONDARY_MEMORY_NEEDED_RTX(MODE) \
- gen_rtx_MEM (MODE, gen_rtx_PLUS (Pmode, stack_pointer_rtx, GEN_INT (-16)))
-
-/* Return the maximum number of consecutive registers
- needed to represent mode MODE in a register of class CLASS. */
-#define CLASS_MAX_NREGS(CLASS, MODE) \
- (!TARGET_SNAKE && ((CLASS) == FP_REGS || (CLASS) == FPUPPER_REGS) ? 1 : \
- ((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
-
-/* Stack layout; function entry, exit and calling. */
-
-/* Define this if pushing a word on the stack
- makes the stack pointer a smaller address. */
-/* #define STACK_GROWS_DOWNWARD */
-
-/* Believe it or not. */
-#define ARGS_GROW_DOWNWARD
-
-/* Define this if the nominal address of the stack frame
- is at the high-address end of the local variables;
- that is, each additional local variable allocated
- goes at a more negative offset in the frame. */
-/* #define FRAME_GROWS_DOWNWARD */
-
-/* Offset within stack frame to start allocating local variables at.
- If FRAME_GROWS_DOWNWARD, this is the offset to the END of the
- first local allocated. Otherwise, it is the offset to the BEGINNING
- of the first local allocated. */
-#define STARTING_FRAME_OFFSET 8
-
-/* If we generate an insn to push BYTES bytes,
- this says how many the stack pointer really advances by.
- On the HP-PA, don't define this because there are no push insns. */
-/* #define PUSH_ROUNDING(BYTES) */
-
-/* Offset of first parameter from the argument pointer register value.
- This value will be negated because the arguments grow down.
- Also note that on STACK_GROWS_UPWARD machines (such as this one)
- this is the distance from the frame pointer to the end of the first
- argument, not it's beginning. To get the real offset of the first
- argument, the size of the argument must be added.
-
- ??? Have to check on this.*/
-
-#define FIRST_PARM_OFFSET(FNDECL) -32
-
-/* Absolute value of offset from top-of-stack address to location to store the
- function parameter if it can't go in a register.
- Addresses for following parameters are computed relative to this one. */
-#define FIRST_PARM_CALLER_OFFSET(FNDECL) -32
-
-
-/* When a parameter is passed in a register, stack space is still
- allocated for it. */
-#define REG_PARM_STACK_SPACE(DECL) 16
-
-/* Define this if the above stack space is to be considered part of the
- space allocated by the caller. */
-#define OUTGOING_REG_PARM_STACK_SPACE
-
-/* Keep the stack pointer constant throughout the function.
- This is both an optimization and a necessity: longjmp
- doesn't behave itself when the stack pointer moves within
- the function! */
-#define ACCUMULATE_OUTGOING_ARGS
-
-/* The weird HPPA calling conventions require a minimum of 48 bytes on
- the stack: 16 bytes for register saves, and 32 bytes for magic.
- This is the difference between the logical top of stack and the
- actual sp. */
-#define STACK_POINTER_OFFSET -32
-
-#define STACK_DYNAMIC_OFFSET(FNDECL) \
- ((STACK_POINTER_OFFSET) - current_function_outgoing_args_size)
-
-/* Value is 1 if returning from a function call automatically
- pops the arguments described by the number-of-args field in the call.
- FUNDECL is the declaration node of the function (as a tree),
- FUNTYPE is the data type of the function (as a tree),
- or for a library call it is an identifier node for the subroutine name. */
-
-#define RETURN_POPS_ARGS(FUNDECL,FUNTYPE,SIZE) 0
-
-/* Define how to find the value returned by a function.
- VALTYPE is the data type of the value (as a tree).
- If the precise function being called is known, FUNC is its FUNCTION_DECL;
- otherwise, FUNC is 0. */
-
-/* On the HP-PA the value is found in register(s) 28(-29), unless
- the mode is SF or DF. Then the value is returned in fr4 (32, ) */
-
-
-#define FUNCTION_VALUE(VALTYPE, FUNC) \
- gen_rtx_REG (TYPE_MODE (VALTYPE), ((! TARGET_SOFT_FLOAT \
- && (TYPE_MODE (VALTYPE) == SFmode || \
- TYPE_MODE (VALTYPE) == DFmode)) ? \
- 32 : 28))
-
-/* Define how to find the value returned by a library function
- assuming the value has mode MODE. */
-
-#define LIBCALL_VALUE(MODE) \
- gen_rtx_REG (MODE, \
- (! TARGET_SOFT_FLOAT \
- && ((MODE) == SFmode || (MODE) == DFmode) ? 32 : 28))
-
-/* 1 if N is a possible register number for a function value
- as seen by the caller. */
-
-#define FUNCTION_VALUE_REGNO_P(N) \
- ((N) == 28 || (! TARGET_SOFT_FLOAT && (N) == 32))
-
-/* 1 if N is a possible register number for function argument passing. */
-
-#define FUNCTION_ARG_REGNO_P(N) \
- (((N) >= 23 && (N) <= 26) || (! TARGET_SOFT_FLOAT && (N) >= 32 && (N) <= 39))
-
-/* Define a data type for recording info about an argument list
- during the scan of that argument list. This data type should
- hold all necessary information about the function itself
- and about the args processed so far, enough to enable macros
- such as FUNCTION_ARG to determine where the next arg should go.
-
- On the HP-PA, this is a single integer, which is a number of words
- of arguments scanned so far (including the invisible argument,
- if any, which holds the structure-value-address).
- Thus 4 or more means all following args should go on the stack. */
-
-struct hppa_args {int words, nargs_prototype, indirect; };
-
-#define CUMULATIVE_ARGS struct hppa_args
-
-/* Initialize a variable CUM of type CUMULATIVE_ARGS
- for a call to a function whose data type is FNTYPE.
- For a library call, FNTYPE is 0. */
-
-#define INIT_CUMULATIVE_ARGS(CUM,FNTYPE,LIBNAME,INDIRECT) \
- (CUM).words = 0, \
- (CUM).indirect = INDIRECT, \
- (CUM).nargs_prototype = (FNTYPE && TYPE_ARG_TYPES (FNTYPE) \
- ? (list_length (TYPE_ARG_TYPES (FNTYPE)) - 1 \
- + (TYPE_MODE (TREE_TYPE (FNTYPE)) == BLKmode \
- || RETURN_IN_MEMORY (TREE_TYPE (FNTYPE)))) \
- : 0)
-
-
-
-/* Similar, but when scanning the definition of a procedure. We always
- set NARGS_PROTOTYPE large so we never return a PARALLEL. */
-
-#define INIT_CUMULATIVE_INCOMING_ARGS(CUM,FNTYPE,IGNORE) \
- (CUM).words = 0, \
- (CUM).indirect = 0, \
- (CUM).nargs_prototype = 1000
-
-/* Figure out the size in words of the function argument. */
-
-#define FUNCTION_ARG_SIZE(MODE, TYPE) \
- ((((MODE) != BLKmode ? GET_MODE_SIZE (MODE) : int_size_in_bytes (TYPE))+3)/4)
-
-/* Update the data in CUM to advance over an argument
- of mode MODE and data type TYPE.
- (TYPE is null for libcalls where that information may not be available.) */
-
-#define FUNCTION_ARG_ADVANCE(CUM, MODE, TYPE, NAMED) \
-{ (CUM).nargs_prototype--; \
- ((((CUM).words & 01) && (TYPE) != 0 \
- && FUNCTION_ARG_SIZE(MODE, TYPE) > 1) \
- && (CUM).words++), \
- (CUM).words += FUNCTION_ARG_SIZE(MODE, TYPE); \
-}
-
-/* Determine where to put an argument to a function.
- Value is zero to push the argument on the stack,
- or a hard register in which to store the argument.
-
- MODE is the argument's machine mode.
- TYPE is the data type of the argument (as a tree).
- This is null for libcalls where that information may
- not be available.
- CUM is a variable of type CUMULATIVE_ARGS which gives info about
- the preceding args and about the function being called.
- NAMED is nonzero if this argument is a named parameter
- (otherwise it is an extra parameter matching an ellipsis).
-
- On the HP-PA the first four words of args are normally in registers
- and the rest are pushed. But any arg that won't entirely fit in regs
- is pushed.
-
- Arguments passed in registers are either 1 or 2 words long.
-
- The caller must make a distinction between calls to explicitly named
- functions and calls through pointers to functions -- the conventions
- are different! Calls through pointers to functions only use general
- registers for the first four argument words.
-
- Of course all this is different for the portable runtime model
- HP wants everyone to use for ELF. Ugh. Here's a quick description
- of how it's supposed to work.
-
- 1) callee side remains unchanged. It expects integer args to be
- in the integer registers, float args in the float registers and
- unnamed args in integer registers.
-
- 2) caller side now depends on if the function being called has
- a prototype in scope (rather than if it's being called indirectly).
-
- 2a) If there is a prototype in scope, then arguments are passed
- according to their type (ints in integer registers, floats in float
- registers, unnamed args in integer registers.
-
- 2b) If there is no prototype in scope, then floating point arguments
- are passed in both integer and float registers. egad.
-
- FYI: The portable parameter passing conventions are almost exactly like
- the standard parameter passing conventions on the RS6000. That's why
- you'll see lots of similar code in rs6000.h. */
-
-#define FUNCTION_ARG_PADDING(MODE, TYPE) function_arg_padding ((MODE), (TYPE))
-
-/* Do not expect to understand this without reading it several times. I'm
- tempted to try and simply it, but I worry about breaking something. */
-
-#define FUNCTION_ARG(CUM, MODE, TYPE, NAMED) \
- (4 >= ((CUM).words + FUNCTION_ARG_SIZE ((MODE), (TYPE))) \
- ? (!TARGET_PORTABLE_RUNTIME || (TYPE) == 0 \
- || !FLOAT_MODE_P (MODE) || TARGET_SOFT_FLOAT \
- || (CUM).nargs_prototype > 0) \
- ? gen_rtx_REG ((MODE), \
- (FUNCTION_ARG_SIZE ((MODE), (TYPE)) > 1 \
- ? (((!(CUM).indirect \
- || TARGET_PORTABLE_RUNTIME) \
- && (MODE) == DFmode \
- && ! TARGET_SOFT_FLOAT) \
- ? ((CUM).words ? 38 : 34) \
- : ((CUM).words ? 23 : 25)) \
- : (((!(CUM).indirect \
- || TARGET_PORTABLE_RUNTIME) \
- && (MODE) == SFmode \
- && ! TARGET_SOFT_FLOAT) \
- ? (32 + 2 * (CUM).words) \
- : (27 - (CUM).words - FUNCTION_ARG_SIZE ((MODE), \
- (TYPE))))))\
- /* We are calling a non-prototyped function with floating point \
- arguments using the portable conventions. */ \
- : gen_rtx_PARALLEL ((MODE), \
- gen_rtvec \
- (2, \
- gen_rtx_EXPR_LIST (VOIDmode, \
- gen_rtx_REG ((MODE), \
- (FUNCTION_ARG_SIZE ((MODE), (TYPE)) > 1 \
- ? ((CUM).words ? 38 : 34) \
- : (32 + 2 * (CUM).words))), \
- const0_rtx), \
- gen_rtx_EXPR_LIST (VOIDmode, \
- gen_rtx_REG ((MODE), \
- (FUNCTION_ARG_SIZE ((MODE), (TYPE)) > 1 \
- ? ((CUM).words ? 23 : 25) \
- : (27 - (CUM).words - \
- FUNCTION_ARG_SIZE ((MODE), \
- (TYPE))))), \
- const0_rtx))) \
- /* Pass this parameter in the stack. */ \
- : 0)
-
-/* For an arg passed partly in registers and partly in memory,
- this is the number of registers used.
- For args passed entirely in registers or entirely in memory, zero. */
-
-#define FUNCTION_ARG_PARTIAL_NREGS(CUM, MODE, TYPE, NAMED) 0
-
-/* If defined, a C expression that gives the alignment boundary, in
- bits, of an argument with the specified mode and type. If it is
- not defined, `PARM_BOUNDARY' is used for all arguments. */
-
-#define FUNCTION_ARG_BOUNDARY(MODE, TYPE) \
- (((TYPE) != 0) \
- ? (((int_size_in_bytes (TYPE)) + 3) / 4) * BITS_PER_WORD \
- : ((GET_MODE_ALIGNMENT(MODE) <= PARM_BOUNDARY) \
- ? PARM_BOUNDARY \
- : GET_MODE_ALIGNMENT(MODE)))
-
-/* Arguments larger than eight bytes are passed by invisible reference */
-
-#define FUNCTION_ARG_PASS_BY_REFERENCE(CUM, MODE, TYPE, NAMED) \
- ((TYPE) && int_size_in_bytes (TYPE) > 8)
-
-#define FUNCTION_ARG_CALLEE_COPIES(CUM, MODE, TYPE, NAMED) \
- ((TYPE) && int_size_in_bytes (TYPE) > 8)
-
-
-extern struct rtx_def *hppa_compare_op0, *hppa_compare_op1;
-extern enum cmp_type hppa_branch_type;
-
-/* Output the label for a function definition. */
-#ifndef HP_FP_ARG_DESCRIPTOR_REVERSED
-#define ASM_DOUBLE_ARG_DESCRIPTORS(FILE, ARG0, ARG1) \
- do { fprintf (FILE, ",ARGW%d=FR", (ARG0)); \
- fprintf (FILE, ",ARGW%d=FU", (ARG1));} while (0)
-#define DFMODE_RETURN_STRING ",RTNVAL=FU"
-#define SFMODE_RETURN_STRING ",RTNVAL=FR"
-#else
-#define ASM_DOUBLE_ARG_DESCRIPTORS(FILE, ARG0, ARG1) \
- do { fprintf (FILE, ",ARGW%d=FU", (ARG0)); \
- fprintf (FILE, ",ARGW%d=FR", (ARG1));} while (0)
-#define DFMODE_RETURN_STRING ",RTNVAL=FR"
-#define SFMODE_RETURN_STRING ",RTNVAL=FU"
-#endif
-
-#define ASM_OUTPUT_MI_THUNK(FILE, THUNK_FNDECL, DELTA, FUNCTION) \
-{ char *target_name = XSTR (XEXP (DECL_RTL (FUNCTION), 0), 0); \
- STRIP_NAME_ENCODING (target_name, target_name); \
- output_function_prologue (FILE, 0); \
- if (VAL_14_BITS_P (DELTA)) \
- fprintf (FILE, "\tb %s\n\tldo %d(%%r26),%%r26\n", target_name, DELTA); \
- else \
- fprintf (FILE, "\taddil L%%%d,%%r26\n\tb %s\n\tldo R%%%d(%%r1),%%r26\n", \
- DELTA, target_name, DELTA); \
- fprintf (FILE, "\n\t.EXIT\n\t.PROCEND\n"); \
-}
-
-/* NAME refers to the function's name. If we are placing each function into
- its own section, we need to switch to the section for this function. Note
- that the section name will have a "." prefix. */
-#define ASM_OUTPUT_FUNCTION_PREFIX(FILE, NAME) \
- { \
- char *name; \
- STRIP_NAME_ENCODING (name, NAME); \
- if (!TARGET_PORTABLE_RUNTIME && TARGET_GAS && in_section == in_text) \
- fputs ("\t.NSUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY\n", FILE); \
- else if (! TARGET_PORTABLE_RUNTIME && TARGET_GAS) \
- fprintf (FILE, \
- "\t.SUBSPA .%s\n", name); \
- }
-
-#define ASM_DECLARE_FUNCTION_NAME(FILE, NAME, DECL) \
- do { tree fntype = TREE_TYPE (TREE_TYPE (DECL)); \
- tree tree_type = TREE_TYPE (DECL); \
- tree parm; \
- int i; \
- if (TREE_PUBLIC (DECL) || TARGET_GAS) \
- { extern int current_function_varargs; \
- if (TREE_PUBLIC (DECL)) \
- { \
- fputs ("\t.EXPORT ", FILE); \
- assemble_name (FILE, NAME); \
- fputs (",ENTRY,PRIV_LEV=3", FILE); \
- } \
- else \
- { \
- fputs ("\t.PARAM ", FILE); \
- assemble_name (FILE, NAME); \
- } \
- if (TARGET_PORTABLE_RUNTIME) \
- { \
- fputs (",ARGW0=NO,ARGW1=NO,ARGW2=NO,ARGW3=NO,", FILE); \
- fputs ("RTNVAL=NO\n", FILE); \
- break; \
- } \
- for (parm = DECL_ARGUMENTS (DECL), i = 0; parm && i < 4; \
- parm = TREE_CHAIN (parm)) \
- { \
- if (TYPE_MODE (DECL_ARG_TYPE (parm)) == SFmode \
- && ! TARGET_SOFT_FLOAT) \
- fprintf (FILE, ",ARGW%d=FR", i++); \
- else if (TYPE_MODE (DECL_ARG_TYPE (parm)) == DFmode \
- && ! TARGET_SOFT_FLOAT) \
- { \
- if (i <= 2) \
- { \
- if (i == 1) i++; \
- ASM_DOUBLE_ARG_DESCRIPTORS (FILE, i++, i++); \
- } \
- else \
- break; \
- } \
- else \
- { \
- int arg_size = \
- FUNCTION_ARG_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm)),\
- DECL_ARG_TYPE (parm)); \
- /* Passing structs by invisible reference uses \
- one general register. */ \
- if (arg_size > 2 \
- || TREE_ADDRESSABLE (DECL_ARG_TYPE (parm))) \
- arg_size = 1; \
- if (arg_size == 2 && i <= 2) \
- { \
- if (i == 1) i++; \
- fprintf (FILE, ",ARGW%d=GR", i++); \
- fprintf (FILE, ",ARGW%d=GR", i++); \
- } \
- else if (arg_size == 1) \
- fprintf (FILE, ",ARGW%d=GR", i++); \
- else \
- i += arg_size; \
- } \
- } \
- /* anonymous args */ \
- if ((TYPE_ARG_TYPES (tree_type) != 0 \
- && (TREE_VALUE (tree_last (TYPE_ARG_TYPES (tree_type)))\
- != void_type_node)) \
- || current_function_varargs) \
- { \
- for (; i < 4; i++) \
- fprintf (FILE, ",ARGW%d=GR", i); \
- } \
- if (TYPE_MODE (fntype) == DFmode && ! TARGET_SOFT_FLOAT) \
- fputs (DFMODE_RETURN_STRING, FILE); \
- else if (TYPE_MODE (fntype) == SFmode && ! TARGET_SOFT_FLOAT) \
- fputs (SFMODE_RETURN_STRING, FILE); \
- else if (fntype != void_type_node) \
- fputs (",RTNVAL=GR", FILE); \
- fputs ("\n", FILE); \
- }} while (0)
-
-/* This macro generates the assembly code for function entry.
- FILE is a stdio stream to output the code to.
- SIZE is an int: how many units of temporary storage to allocate.
- Refer to the array `regs_ever_live' to determine which registers
- to save; `regs_ever_live[I]' is nonzero if register number I
- is ever used in the function. This macro is responsible for
- knowing which registers should not be saved even if used. */
-
-/* On HP-PA, move-double insns between fpu and cpu need an 8-byte block
- of memory. If any fpu reg is used in the function, we allocate
- such a block here, at the bottom of the frame, just in case it's needed.
-
- If this function is a leaf procedure, then we may choose not
- to do a "save" insn. The decision about whether or not
- to do this is made in regclass.c. */
-
-#define FUNCTION_PROLOGUE(FILE, SIZE) \
- output_function_prologue (FILE, SIZE)
-
-/* Output assembler code to FILE to increment profiler label # LABELNO
- for profiling a function entry.
-
- Because HPUX _mcount is so different, we actually emit the
- profiling code in function_prologue. This just stores LABELNO for
- that. */
-
-#define PROFILE_BEFORE_PROLOGUE
-#define FUNCTION_PROFILER(FILE, LABELNO) \
-{ extern int hp_profile_labelno; hp_profile_labelno = (LABELNO);}
-
-/* EXIT_IGNORE_STACK should be nonzero if, when returning from a function,
- the stack pointer does not matter. The value is tested only in
- functions that have frame pointers.
- No definition is equivalent to always zero. */
-
-extern int may_call_alloca;
-extern int current_function_pretend_args_size;
-
-#define EXIT_IGNORE_STACK \
- (get_frame_size () != 0 \
- || current_function_calls_alloca || current_function_outgoing_args_size)
-
-
-/* This macro generates the assembly code for function exit,
- on machines that need it. If FUNCTION_EPILOGUE is not defined
- then individual return instructions are generated for each
- return statement. Args are same as for FUNCTION_PROLOGUE.
-
- The function epilogue should not depend on the current stack pointer!
- It should use the frame pointer only. This is mandatory because
- of alloca; we also take advantage of it to omit stack adjustments
- before returning. */
-
-/* This declaration is needed due to traditional/ANSI
- incompatibilities which cannot be #ifdefed away
- because they occur inside of macros. Sigh. */
-extern union tree_node *current_function_decl;
-
-#define FUNCTION_EPILOGUE(FILE, SIZE) \
- output_function_epilogue (FILE, SIZE)
-
-/* Output assembler code for a block containing the constant parts
- of a trampoline, leaving space for the variable parts.\
-
- The trampoline sets the static chain pointer to STATIC_CHAIN_REGNUM
- and then branches to the specified routine.
-
- This code template is copied from text segment to stack location
- and then patched with INITIALIZE_TRAMPOLINE to contain
- valid values, and then entered as a subroutine.
-
- It is best to keep this as small as possible to avoid having to
- flush multiple lines in the cache. */
-
-#define TRAMPOLINE_TEMPLATE(FILE) \
- { \
- fputs ("\tldw 36(0,%r22),%r21\n", FILE); \
- fputs ("\tbb,>=,n %r21,30,.+16\n", FILE); \
- fputs ("\tdepi 0,31,2,%r21\n", FILE); \
- fputs ("\tldw 4(0,%r21),%r19\n", FILE); \
- fputs ("\tldw 0(0,%r21),%r21\n", FILE); \
- fputs ("\tldsid (0,%r21),%r1\n", FILE); \
- fputs ("\tmtsp %r1,%sr0\n", FILE); \
- fputs ("\tbe 0(%sr0,%r21)\n", FILE); \
- fputs ("\tldw 40(0,%r22),%r29\n", FILE); \
- fputs ("\t.word 0\n", FILE); \
- fputs ("\t.word 0\n", FILE); \
- }
-
-/* Length in units of the trampoline for entering a nested function.
-
- Flush the cache entries corresponding to the first and last addresses
- of the trampoline. This is necessary as the trampoline may cross two
- cache lines.
-
- If the code part of the trampoline ever grows to > 32 bytes, then it
- will become necessary to hack on the cacheflush pattern in pa.md. */
-
-#define TRAMPOLINE_SIZE (11 * 4)
-
-/* Emit RTL insns to initialize the variable parts of a trampoline.
- FNADDR is an RTX for the address of the function's pure code.
- CXT is an RTX for the static chain value for the function.
-
- Move the function address to the trampoline template at offset 12.
- Move the static chain value to trampoline template at offset 16. */
-
-#define INITIALIZE_TRAMPOLINE(TRAMP, FNADDR, CXT) \
-{ \
- rtx start_addr, end_addr; \
- \
- start_addr = memory_address (Pmode, plus_constant ((TRAMP), 36)); \
- emit_move_insn (gen_rtx_MEM (Pmode, start_addr), (FNADDR)); \
- start_addr = memory_address (Pmode, plus_constant ((TRAMP), 40)); \
- emit_move_insn (gen_rtx_MEM (Pmode, start_addr), (CXT)); \
- /* fdc and fic only use registers for the address to flush, \
- they do not accept integer displacements. */ \
- start_addr = force_reg (SImode, (TRAMP)); \
- end_addr = force_reg (SImode, plus_constant ((TRAMP), 32)); \
- emit_insn (gen_dcacheflush (start_addr, end_addr)); \
- end_addr = force_reg (SImode, plus_constant (start_addr, 32)); \
- emit_insn (gen_icacheflush (start_addr, end_addr, start_addr, \
- gen_reg_rtx (SImode), gen_reg_rtx (SImode)));\
-}
-
-/* Emit code for a call to builtin_saveregs. We must emit USE insns which
- reference the 4 integer arg registers and 4 fp arg registers.
- Ordinarily they are not call used registers, but they are for
- _builtin_saveregs, so we must make this explicit. */
-
-extern struct rtx_def *hppa_builtin_saveregs ();
-#define EXPAND_BUILTIN_SAVEREGS(ARGLIST) hppa_builtin_saveregs (ARGLIST)
-
-
-/* Addressing modes, and classification of registers for them. */
-/* CYGNUS LOCAL PA8000/law */
-/* It is advisable to avoid autoincrement addressing modes on the PA8000
- series processors. This definition disables the most critical autoinc
- usages (in loops). When the prologue/epilogue code is converted we
- can probably disable autoinc entirely for the PA8000. */
-#define HAVE_POST_INCREMENT (pa_cpu == PROCESSOR_8000 ? flow2_completed : 1)
-#define HAVE_POST_DECREMENT (pa_cpu == PROCESSOR_8000 ? flow2_completed : 1)
-
-#define HAVE_PRE_DECREMENT (pa_cpu == PROCESSOR_8000 ? flow2_completed : 1)
-#define HAVE_PRE_INCREMENT (pa_cpu == PROCESSOR_8000 ? flow2_completed : 1)
-/* END CYGNUS LOCAL */
-
-/* Macros to check register numbers against specific register classes. */
-
-/* These assume that REGNO is a hard or pseudo reg number.
- They give nonzero only if REGNO is a hard reg of the suitable class
- or a pseudo reg currently allocated to a suitable hard reg.
- Since they use reg_renumber, they are safe only once reg_renumber
- has been allocated, which happens in local-alloc.c. */
-
-#define REGNO_OK_FOR_INDEX_P(REGNO) \
- ((REGNO) && ((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < 32))
-#define REGNO_OK_FOR_BASE_P(REGNO) \
- ((REGNO) && ((REGNO) < 32 || (unsigned) reg_renumber[REGNO] < 32))
-#define REGNO_OK_FOR_FP_P(REGNO) \
- (FP_REGNO_P (REGNO) || FP_REGNO_P (reg_renumber[REGNO]))
-
-/* Now macros that check whether X is a register and also,
- strictly, whether it is in a specified class.
-
- These macros are specific to the HP-PA, and may be used only
- in code for printing assembler insns and in conditions for
- define_optimization. */
-
-/* 1 if X is an fp register. */
-
-#define FP_REG_P(X) (REG_P (X) && REGNO_OK_FOR_FP_P (REGNO (X)))
-
-/* Maximum number of registers that can appear in a valid memory address. */
-
-#define MAX_REGS_PER_ADDRESS 2
-
-/* Recognize any constant value that is a valid address except
- for symbolic addresses. We get better CSE by rejecting them
- here and allowing hppa_legitimize_address to break them up. We
- use most of the constants accepted by CONSTANT_P, except CONST_DOUBLE. */
-
-#define CONSTANT_ADDRESS_P(X) \
- ((GET_CODE (X) == LABEL_REF || GET_CODE (X) == SYMBOL_REF \
- || GET_CODE (X) == CONST_INT || GET_CODE (X) == CONST \
- || GET_CODE (X) == HIGH) \
- && (reload_in_progress || reload_completed || ! symbolic_expression_p (X)))
-
-/* Include all constant integers and constant doubles, but not
- floating-point, except for floating-point zero.
-
- Reject LABEL_REFs if we're not using gas or the new HP assembler. */
-#ifdef NEW_HP_ASSEMBLER
-#define LEGITIMATE_CONSTANT_P(X) \
- ((GET_MODE_CLASS (GET_MODE (X)) != MODE_FLOAT \
- || (X) == CONST0_RTX (GET_MODE (X))) \
- && !function_label_operand (X, VOIDmode))
-#else
-#define LEGITIMATE_CONSTANT_P(X) \
- ((GET_MODE_CLASS (GET_MODE (X)) != MODE_FLOAT \
- || (X) == CONST0_RTX (GET_MODE (X))) \
- && (GET_CODE (X) != LABEL_REF || TARGET_GAS)\
- && !function_label_operand (X, VOIDmode))
-#endif
-
-/* Subroutine for EXTRA_CONSTRAINT.
-
- Return 1 iff OP is a pseudo which did not get a hard register and
- we are running the reload pass. */
-
-#define IS_RELOADING_PSEUDO_P(OP) \
- ((reload_in_progress \
- && GET_CODE (OP) == REG \
- && REGNO (OP) >= FIRST_PSEUDO_REGISTER \
- && reg_renumber [REGNO (OP)] < 0))
-
-/* CYGNUS LOCAL PA8000/law */
-/* Optional extra constraints for this machine. Borrowed from sparc.h.
-
- For the HPPA, `Q' means that this is a memory operand but not a
- symbolic memory operand. Note that an unassigned pseudo register
- is such a memory operand. Needed because reload will generate
- these things in insns and then not re-recognize the insns, causing
- constrain_operands to fail.
-
- `R' is for certain scaled indexed addresses
-
- `S' is the constant 31.
-
- `T' is for fp loads and stores. */
-#define EXTRA_CONSTRAINT(OP, C) \
- ((C) == 'Q' ? \
- (IS_RELOADING_PSEUDO_P (OP) \
- || (GET_CODE (OP) == MEM \
- && (memory_address_p (GET_MODE (OP), XEXP (OP, 0))\
- || reload_in_progress) \
- && ! symbolic_memory_operand (OP, VOIDmode) \
- && !(GET_CODE (XEXP (OP, 0)) == PLUS \
- && (GET_CODE (XEXP (XEXP (OP, 0), 0)) == MULT\
- || GET_CODE (XEXP (XEXP (OP, 0), 1)) == MULT))))\
- : ((C) == 'R' ? \
- (GET_CODE (OP) == MEM \
- && GET_CODE (XEXP (OP, 0)) == PLUS \
- && (GET_CODE (XEXP (XEXP (OP, 0), 0)) == MULT \
- || GET_CODE (XEXP (XEXP (OP, 0), 1)) == MULT) \
- && (move_operand (OP, GET_MODE (OP)) \
- || memory_address_p (GET_MODE (OP), XEXP (OP, 0))\
- || reload_in_progress)) \
- : ((C) == 'T' ? \
- (GET_CODE (OP) == MEM \
- /* Using DFmode forces only short displacements \
- to be recognized as valid in reg+d addresses. */\
- && memory_address_p (DFmode, XEXP (OP, 0)) \
- && !(GET_CODE (XEXP (OP, 0)) == PLUS \
- && (GET_CODE (XEXP (XEXP (OP, 0), 0)) == MULT\
- || GET_CODE (XEXP (XEXP (OP, 0), 1)) == MULT))) \
- : ((C) == 'S' ? \
- (GET_CODE (OP) == CONST_INT && INTVAL (OP) == 31) : 0))))
-/* END CYGNUS LOCAL */
-
-
-/* The macros REG_OK_FOR..._P assume that the arg is a REG rtx
- and check its validity for a certain class.
- We have two alternate definitions for each of them.
- The usual definition accepts all pseudo regs; the other rejects
- them unless they have been allocated suitable hard regs.
- The symbol REG_OK_STRICT causes the latter definition to be used.
-
- Most source files want to accept pseudo regs in the hope that
- they will get allocated to the class that the insn wants them to be in.
- Source files for reload pass need to be strict.
- After reload, it makes no difference, since pseudo regs have
- been eliminated by then. */
-
-#ifndef REG_OK_STRICT
-
-/* Nonzero if X is a hard reg that can be used as an index
- or if it is a pseudo reg. */
-#define REG_OK_FOR_INDEX_P(X) \
-(REGNO (X) && (REGNO (X) < 32 || REGNO (X) >= FIRST_PSEUDO_REGISTER))
-/* Nonzero if X is a hard reg that can be used as a base reg
- or if it is a pseudo reg. */
-#define REG_OK_FOR_BASE_P(X) \
-(REGNO (X) && (REGNO (X) < 32 || REGNO (X) >= FIRST_PSEUDO_REGISTER))
-
-#else
-
-/* Nonzero if X is a hard reg that can be used as an index. */
-#define REG_OK_FOR_INDEX_P(X) REGNO_OK_FOR_INDEX_P (REGNO (X))
-/* Nonzero if X is a hard reg that can be used as a base reg. */
-#define REG_OK_FOR_BASE_P(X) REGNO_OK_FOR_BASE_P (REGNO (X))
-
-#endif
-
-/* GO_IF_LEGITIMATE_ADDRESS recognizes an RTL expression
- that is a valid memory address for an instruction.
- The MODE argument is the machine mode for the MEM expression
- that wants to use this address.
-
- On the HP-PA, the actual legitimate addresses must be
- REG+REG, REG+(REG*SCALE) or REG+SMALLINT.
- But we can treat a SYMBOL_REF as legitimate if it is part of this
- function's constant-pool, because such addresses can actually
- be output as REG+SMALLINT.
-
- Note we only allow 5 bit immediates for access to a constant address;
- doing so avoids losing for loading/storing a FP register at an address
- which will not fit in 5 bits. */
-
-#define VAL_5_BITS_P(X) ((unsigned)(X) + 0x10 < 0x20)
-#define INT_5_BITS(X) VAL_5_BITS_P (INTVAL (X))
-
-#define VAL_U5_BITS_P(X) ((unsigned)(X) < 0x20)
-#define INT_U5_BITS(X) VAL_U5_BITS_P (INTVAL (X))
-
-#define VAL_11_BITS_P(X) ((unsigned)(X) + 0x400 < 0x800)
-#define INT_11_BITS(X) VAL_11_BITS_P (INTVAL (X))
-
-#define VAL_14_BITS_P(X) ((unsigned)(X) + 0x2000 < 0x4000)
-#define INT_14_BITS(X) VAL_14_BITS_P (INTVAL (X))
-
-#define GO_IF_LEGITIMATE_ADDRESS(MODE, X, ADDR) \
-{ \
- if ((REG_P (X) && REG_OK_FOR_BASE_P (X)) \
- || ((GET_CODE (X) == PRE_DEC || GET_CODE (X) == POST_DEC \
- || GET_CODE (X) == PRE_INC || GET_CODE (X) == POST_INC) \
- && REG_P (XEXP (X, 0)) \
- && REG_OK_FOR_BASE_P (XEXP (X, 0)))) \
- goto ADDR; \
- else if (GET_CODE (X) == PLUS) \
- { \
- rtx base = 0, index = 0; \
- if (flag_pic && XEXP (X, 0) == pic_offset_table_rtx)\
- { \
- if (GET_CODE (XEXP (X, 1)) == REG \
- && REG_OK_FOR_BASE_P (XEXP (X, 1))) \
- goto ADDR; \
- else if (flag_pic == 1 \
- && GET_CODE (XEXP (X, 1)) == SYMBOL_REF)\
- goto ADDR; \
- } \
- else if (REG_P (XEXP (X, 0)) \
- && REG_OK_FOR_BASE_P (XEXP (X, 0))) \
- base = XEXP (X, 0), index = XEXP (X, 1); \
- else if (REG_P (XEXP (X, 1)) \
- && REG_OK_FOR_BASE_P (XEXP (X, 1))) \
- base = XEXP (X, 1), index = XEXP (X, 0); \
- if (base != 0) \
- if (GET_CODE (index) == CONST_INT \
- && ((INT_14_BITS (index) \
- && (TARGET_SOFT_FLOAT \
- /* CYGNUS LOCAL pa8000/law */ \
- || (TARGET_PARISC_2_0 \
- && ((MODE == SFmode \
- && (INTVAL (index) % 4) == 0)\
- || (MODE == DFmode \
- && (INTVAL (index) % 8) == 0)))\
- /* END CYGNUS LOCAL pa8000/law */ \
- || ((MODE) != SFmode && (MODE) != DFmode))) \
- || INT_5_BITS (index))) \
- goto ADDR; \
- if (! TARGET_SOFT_FLOAT \
- && ! TARGET_DISABLE_INDEXING \
- && base \
- && (mode == SFmode || mode == DFmode) \
- && GET_CODE (index) == MULT \
- && GET_CODE (XEXP (index, 0)) == REG \
- && REG_OK_FOR_BASE_P (XEXP (index, 0)) \
- && GET_CODE (XEXP (index, 1)) == CONST_INT \
- && INTVAL (XEXP (index, 1)) == (mode == SFmode ? 4 : 8))\
- goto ADDR; \
- } \
- else if (GET_CODE (X) == LO_SUM \
- && GET_CODE (XEXP (X, 0)) == REG \
- && REG_OK_FOR_BASE_P (XEXP (X, 0)) \
- && CONSTANT_P (XEXP (X, 1)) \
- && (TARGET_SOFT_FLOAT \
- || ((MODE) != SFmode \
- && (MODE) != DFmode))) \
- goto ADDR; \
- else if (GET_CODE (X) == LO_SUM \
- && GET_CODE (XEXP (X, 0)) == SUBREG \
- && GET_CODE (SUBREG_REG (XEXP (X, 0))) == REG\
- && REG_OK_FOR_BASE_P (SUBREG_REG (XEXP (X, 0)))\
- && CONSTANT_P (XEXP (X, 1)) \
- && (TARGET_SOFT_FLOAT \
- || ((MODE) != SFmode \
- && (MODE) != DFmode))) \
- goto ADDR; \
- else if (GET_CODE (X) == LABEL_REF \
- || (GET_CODE (X) == CONST_INT \
- && INT_5_BITS (X))) \
- goto ADDR; \
- /* Needed for -fPIC */ \
- else if (GET_CODE (X) == LO_SUM \
- && GET_CODE (XEXP (X, 0)) == REG \
- && REG_OK_FOR_BASE_P (XEXP (X, 0)) \
- && GET_CODE (XEXP (X, 1)) == UNSPEC) \
- goto ADDR; \
-}
-
-/* Look for machine dependent ways to make the invalid address AD a
- valid address.
-
- For the PA, transform:
-
- memory(X + <large int>)
-
- into:
-
- if (<large int> & mask) >= 16
- Y = (<large int> & ~mask) + mask + 1 Round up.
- else
- Y = (<large int> & ~mask) Round down.
- Z = X + Y
- memory (Z + (<large int> - Y));
-
- This makes reload inheritance and reload_cse work better since Z
- can be reused.
-
- There may be more opportunities to improve code with this hook. */
-#define LEGITIMIZE_RELOAD_ADDRESS(AD, MODE, OPNUM, TYPE, IND, WIN) \
-do { \
- int offset, newoffset, mask; \
- rtx new, temp = NULL_RTX; \
- mask = GET_MODE_CLASS (MODE) == MODE_FLOAT ? 0x1f : 0x3fff; \
- \
- /* CYGNUS LOCAL pa8000/law */ \
- mask = (GET_MODE_CLASS (MODE) == MODE_FLOAT \
- ? (TARGET_PARISC_2_0 ? 0x3fff : 0x1f) : 0x3fff); \
- /* END CYGNUS LOCAL */ \
- \
- if (optimize \
- && GET_CODE (AD) == PLUS) \
- temp = simplify_binary_operation (PLUS, Pmode, \
- XEXP (AD, 0), XEXP (AD, 1)); \
- \
- new = temp ? temp : AD; \
- \
- if (optimize \
- && GET_CODE (new) == PLUS \
- && GET_CODE (XEXP (new, 0)) == REG \
- && GET_CODE (XEXP (new, 1)) == CONST_INT) \
- { \
- offset = INTVAL (XEXP ((new), 1)); \
- \
- /* Choose rounding direction. Round up if we are >= halfway. */ \
- if ((offset & mask) >= ((mask + 1) / 2)) \
- newoffset = (offset & ~mask) + mask + 1; \
- else \
- newoffset = offset & ~mask; \
- \
- if (newoffset != 0 \
- && VAL_14_BITS_P (newoffset)) \
- { \
- \
- temp = gen_rtx_PLUS (Pmode, XEXP (new, 0), \
- GEN_INT (newoffset)); \
- AD = gen_rtx_PLUS (Pmode, temp, GEN_INT (offset - newoffset));\
- push_reload (XEXP (AD, 0), 0, &XEXP (AD, 0), 0, \
- BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, \
- (OPNUM), (TYPE)); \
- goto WIN; \
- } \
- } \
-} while (0)
-
-
-
-
-/* Try machine-dependent ways of modifying an illegitimate address
- to be legitimate. If we find one, return the new, valid address.
- This macro is used in only one place: `memory_address' in explow.c.
-
- OLDX is the address as it was before break_out_memory_refs was called.
- In some cases it is useful to look at this to decide what needs to be done.
-
- MODE and WIN are passed so that this macro can use
- GO_IF_LEGITIMATE_ADDRESS.
-
- It is always safe for this macro to do nothing. It exists to recognize
- opportunities to optimize the output. */
-
-extern struct rtx_def *hppa_legitimize_address ();
-#define LEGITIMIZE_ADDRESS(X, OLDX, MODE, WIN) \
-{ rtx orig_x = (X); \
- (X) = hppa_legitimize_address (X, OLDX, MODE); \
- if ((X) != orig_x && memory_address_p (MODE, X)) \
- goto WIN; }
-
-/* Go to LABEL if ADDR (a legitimate address expression)
- has an effect that depends on the machine mode it is used for. */
-
-#define GO_IF_MODE_DEPENDENT_ADDRESS(ADDR,LABEL) \
- if (GET_CODE (ADDR) == PRE_DEC \
- || GET_CODE (ADDR) == POST_DEC \
- || GET_CODE (ADDR) == PRE_INC \
- || GET_CODE (ADDR) == POST_INC) \
- goto LABEL
-
-/* Define this macro if references to a symbol must be treated
- differently depending on something about the variable or
- function named by the symbol (such as what section it is in).
-
- The macro definition, if any, is executed immediately after the
- rtl for DECL or other node is created.
- The value of the rtl will be a `mem' whose address is a
- `symbol_ref'.
-
- The usual thing for this macro to do is to a flag in the
- `symbol_ref' (such as `SYMBOL_REF_FLAG') or to store a modified
- name string in the `symbol_ref' (if one bit is not enough
- information).
-
- On the HP-PA we use this to indicate if a symbol is in text or
- data space. Also, function labels need special treatment. */
-
-#define TEXT_SPACE_P(DECL)\
- (TREE_CODE (DECL) == FUNCTION_DECL \
- || (TREE_CODE (DECL) == VAR_DECL \
- && TREE_READONLY (DECL) && ! TREE_SIDE_EFFECTS (DECL) \
- && (! DECL_INITIAL (DECL) || ! reloc_needed (DECL_INITIAL (DECL))) \
- && !flag_pic) \
- || (TREE_CODE_CLASS (TREE_CODE (DECL)) == 'c' \
- && !(TREE_CODE (DECL) == STRING_CST && flag_writable_strings)))
-
-#define FUNCTION_NAME_P(NAME) \
-(*(NAME) == '@' || (*(NAME) == '*' && *((NAME) + 1) == '@'))
-
-#define ENCODE_SECTION_INFO(DECL)\
-do \
- { if (TEXT_SPACE_P (DECL)) \
- { rtx _rtl; \
- if (TREE_CODE (DECL) == FUNCTION_DECL \
- || TREE_CODE (DECL) == VAR_DECL) \
- _rtl = DECL_RTL (DECL); \
- else \
- _rtl = TREE_CST_RTL (DECL); \
- SYMBOL_REF_FLAG (XEXP (_rtl, 0)) = 1; \
- if (TREE_CODE (DECL) == FUNCTION_DECL) \
- hppa_encode_label (XEXP (DECL_RTL (DECL), 0), 0);\
- } \
- } \
-while (0)
-
-/* Store the user-specified part of SYMBOL_NAME in VAR.
- This is sort of inverse to ENCODE_SECTION_INFO. */
-
-#define STRIP_NAME_ENCODING(VAR,SYMBOL_NAME) \
- (VAR) = ((SYMBOL_NAME) + ((SYMBOL_NAME)[0] == '*' ? \
- 1 + (SYMBOL_NAME)[1] == '@'\
- : (SYMBOL_NAME)[0] == '@'))
-
-/* On hpux10, the linker will give an error if we have a reference
- in the read-only data section to a symbol defined in a shared
- library. Therefore, expressions that might require a reloc can
- not be placed in the read-only data section. */
-#define SELECT_SECTION(EXP,RELOC) \
- if (TREE_CODE (EXP) == VAR_DECL \
- && TREE_READONLY (EXP) \
- && !TREE_THIS_VOLATILE (EXP) \
- && DECL_INITIAL (EXP) \
- && (DECL_INITIAL (EXP) == error_mark_node \
- || TREE_CONSTANT (DECL_INITIAL (EXP))) \
- && !RELOC) \
- readonly_data_section (); \
- else if (TREE_CODE_CLASS (TREE_CODE (EXP)) == 'c' \
- && !(TREE_CODE (EXP) == STRING_CST && flag_writable_strings) \
- && !RELOC) \
- readonly_data_section (); \
- else \
- data_section ();
-
-/* Arghh. The hpux10 linker chokes if we have a reference to symbols
- in a readonly data section when the symbol is defined in a shared
- library. Since we can't know at compile time if a symbol will be
- satisfied by a shared library or main program we put any symbolic
- constant into the normal data section. */
-#define SELECT_RTX_SECTION(MODE,RTX) \
- if (symbolic_operand (RTX, MODE)) \
- data_section (); \
- else \
- readonly_data_section ();
-
-/* Specify the machine mode that this machine uses
- for the index in the tablejump instruction. */
-#define CASE_VECTOR_MODE (TARGET_BIG_SWITCH ? TImode : DImode)
-
-/* Specify the tree operation to be used to convert reals to integers. */
-#define IMPLICIT_FIX_EXPR FIX_ROUND_EXPR
-
-/* This is the kind of divide that is easiest to do in the general case. */
-#define EASY_DIV_EXPR TRUNC_DIV_EXPR
-
-/* Define this as 1 if `char' should by default be signed; else as 0. */
-#define DEFAULT_SIGNED_CHAR 1
-
-/* Max number of bytes we can move from memory to memory
- in one reasonably fast instruction. */
-#define MOVE_MAX 8
-
-/* Higher than the default as we prefer to use simple move insns
- (better scheduling and delay slot filling) and because our
- built-in block move is really a 2X unrolled loop. */
-#define MOVE_RATIO 4
-
-/* Define if operations between registers always perform the operation
- on the full register even if a narrower mode is specified. */
-#define WORD_REGISTER_OPERATIONS
-
-/* Define if loading in MODE, an integral mode narrower than BITS_PER_WORD
- will either zero-extend or sign-extend. The value of this macro should
- be the code that says which one of the two operations is implicitly
- done, NIL if none. */
-#define LOAD_EXTEND_OP(MODE) ZERO_EXTEND
-
-/* Nonzero if access to memory by bytes is slow and undesirable. */
-#define SLOW_BYTE_ACCESS 1
-
-/* Do not break .stabs pseudos into continuations.
-
- This used to be zero (no max length), but big enums and such can
- cause huge strings which killed gas.
-
- We also have to avoid lossage in dbxout.c -- it does not compute the
- string size accurately, so we are real conservative here. */
-#define DBX_CONTIN_LENGTH 3000
-
-/* Value is 1 if truncating an integer of INPREC bits to OUTPREC bits
- is done just by pretending it is already truncated. */
-#define TRULY_NOOP_TRUNCATION(OUTPREC, INPREC) 1
-
-/* We assume that the store-condition-codes instructions store 0 for false
- and some other value for true. This is the value stored for true. */
-
-#define STORE_FLAG_VALUE 1
-
-/* When a prototype says `char' or `short', really pass an `int'. */
-#define PROMOTE_PROTOTYPES
-
-/* Specify the machine mode that pointers have.
- After generation of rtl, the compiler makes no further distinction
- between pointers and any other objects of this machine mode. */
-#define Pmode SImode
-
-/* Add any extra modes needed to represent the condition code.
-
- HPPA floating comparisons produce condition codes. */
-#define EXTRA_CC_MODES CCFPmode
-
-/* Define the names for the modes specified above. */
-#define EXTRA_CC_NAMES "CCFP"
-
-/* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
- return the mode to be used for the comparison. For floating-point, CCFPmode
- should be used. CC_NOOVmode should be used when the first operand is a
- PLUS, MINUS, or NEG. CCmode should be used when no special processing is
- needed. */
-#define SELECT_CC_MODE(OP,X,Y) \
- (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT ? CCFPmode : CCmode) \
-
-/* A function address in a call instruction
- is a byte address (for indexing purposes)
- so give the MEM rtx a byte's mode. */
-#define FUNCTION_MODE SImode
-
-/* Define this if addresses of constant functions
- shouldn't be put through pseudo regs where they can be cse'd.
- Desirable on machines where ordinary constants are expensive
- but a CALL with constant address is cheap. */
-#define NO_FUNCTION_CSE
-
-/* Define this to be nonzero if shift instructions ignore all but the low-order
- few bits. */
-#define SHIFT_COUNT_TRUNCATED 1
-
-/* Use atexit for static constructors/destructors, instead of defining
- our own exit function. */
-#define HAVE_ATEXIT
-
-/* Compute the cost of computing a constant rtl expression RTX
- whose rtx-code is CODE. The body of this macro is a portion
- of a switch statement. If the code is computed here,
- return it with a return statement. Otherwise, break from the switch. */
-
-#define CONST_COSTS(RTX,CODE,OUTER_CODE) \
- case CONST_INT: \
- if (INTVAL (RTX) == 0) return 0; \
- if (INT_14_BITS (RTX)) return 1; \
- case HIGH: \
- return 2; \
- case CONST: \
- case LABEL_REF: \
- case SYMBOL_REF: \
- return 4; \
- case CONST_DOUBLE: \
- if ((RTX == CONST0_RTX (DFmode) || RTX == CONST0_RTX (SFmode)) \
- && OUTER_CODE != SET) \
- return 0; \
- else \
- return 8;
-
-#define ADDRESS_COST(RTX) \
- (GET_CODE (RTX) == REG ? 1 : hppa_address_cost (RTX))
-
-/* Compute extra cost of moving data between one register class
- and another.
-
- Make moves from SAR so expensive they should never happen. We used to
- have 0xffff here, but that generates overflow in rare cases.
-
- Copies involving a FP register and a non-FP register are relatively
- expensive because they must go through memory.
-
- Other copies are reasonably cheap. */
-#define REGISTER_MOVE_COST(CLASS1, CLASS2) \
- (CLASS1 == SHIFT_REGS ? 0x100 \
- : FP_REG_CLASS_P (CLASS1) && ! FP_REG_CLASS_P (CLASS2) ? 16 \
- : FP_REG_CLASS_P (CLASS2) && ! FP_REG_CLASS_P (CLASS1) ? 16 \
- : 2)
-
-
-/* Provide the costs of a rtl expression. This is in the body of a
- switch on CODE. The purpose for the cost of MULT is to encourage
- `synth_mult' to find a synthetic multiply when reasonable. */
-
-#define RTX_COSTS(X,CODE,OUTER_CODE) \
- case MULT: \
- if (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT) \
- return COSTS_N_INSNS (3); \
- return (TARGET_SNAKE && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT) \
- ? COSTS_N_INSNS (8) : COSTS_N_INSNS (20); \
- case DIV: \
- if (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT) \
- return COSTS_N_INSNS (14); \
- case UDIV: \
- case MOD: \
- case UMOD: \
- return COSTS_N_INSNS (60); \
- case PLUS: /* this includes shNadd insns */ \
- case MINUS: \
- if (GET_MODE_CLASS (GET_MODE (X)) == MODE_FLOAT) \
- return COSTS_N_INSNS (3); \
- return COSTS_N_INSNS (1); \
- case ASHIFT: \
- case ASHIFTRT: \
- case LSHIFTRT: \
- return COSTS_N_INSNS (1);
-
-/* Adjust the cost of dependencies. */
-
-#define ADJUST_COST(INSN,LINK,DEP,COST) \
- (COST) = pa_adjust_cost (INSN, LINK, DEP, COST)
-
-/* Adjust scheduling priorities. We use this to try and keep addil
- and the next use of %r1 close together. */
-#define ADJUST_PRIORITY(PREV) \
- { \
- rtx set = single_set (PREV); \
- rtx src, dest; \
- if (set) \
- { \
- src = SET_SRC (set); \
- dest = SET_DEST (set); \
- if (GET_CODE (src) == LO_SUM \
- && symbolic_operand (XEXP (src, 1), VOIDmode) \
- && ! read_only_operand (XEXP (src, 1), VOIDmode)) \
- INSN_PRIORITY (PREV) >>= 3; \
- else if (GET_CODE (src) == MEM \
- && GET_CODE (XEXP (src, 0)) == LO_SUM \
- && symbolic_operand (XEXP (XEXP (src, 0), 1), VOIDmode)\
- && ! read_only_operand (XEXP (XEXP (src, 0), 1), VOIDmode))\
- INSN_PRIORITY (PREV) >>= 1; \
- else if (GET_CODE (dest) == MEM \
- && GET_CODE (XEXP (dest, 0)) == LO_SUM \
- && symbolic_operand (XEXP (XEXP (dest, 0), 1), VOIDmode)\
- && ! read_only_operand (XEXP (XEXP (dest, 0), 1), VOIDmode))\
- INSN_PRIORITY (PREV) >>= 3; \
- } \
- }
-
-/* Handling the special cases is going to get too complicated for a macro,
- just call `pa_adjust_insn_length' to do the real work. */
-#define ADJUST_INSN_LENGTH(INSN, LENGTH) \
- LENGTH += pa_adjust_insn_length (INSN, LENGTH);
-
-/* Millicode insns are actually function calls with some special
- constraints on arguments and register usage.
-
- Millicode calls always expect their arguments in the integer argument
- registers, and always return their result in %r29 (ret1). They
- are expected to clobber their arguments, %r1, %r29, and %r31 and
- nothing else.
-
- These macros tell reorg that the references to arguments and
- register clobbers for millicode calls do not appear to happen
- until after the millicode call. This allows reorg to put insns
- which set the argument registers into the delay slot of the millicode
- call -- thus they act more like traditional CALL_INSNs.
-
- get_attr_type will try to recognize the given insn, so make sure to
- filter out things it will not accept -- SEQUENCE, USE and CLOBBER insns
- in particular. */
-#define INSN_SETS_ARE_DELAYED(X) (insn_sets_and_refs_are_delayed (X))
-#define INSN_REFERENCES_ARE_DELAYED(X) (insn_sets_and_refs_are_delayed (X))
-
-
-/* Control the assembler format that we output. */
-
-/* Output at beginning of assembler file. */
-
-#define ASM_FILE_START(FILE) \
-do { fputs ("\t.SPACE $PRIVATE$\n\
-\t.SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31\n\
-\t.SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82\n\
-\t.SPACE $TEXT$\n\
-\t.SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44\n\
-\t.SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY\n\
-\t.IMPORT $global$,DATA\n\
-\t.IMPORT $$dyncall,MILLICODE\n", FILE);\
- if (profile_flag)\
- fprintf (FILE, "\t.IMPORT _mcount, CODE\n");\
- if (write_symbols != NO_DEBUG) \
- output_file_directive ((FILE), main_input_filename); \
- } while (0)
-
-#define ASM_FILE_END(FILE) output_deferred_plabels (FILE)
-
-/* Output to assembler file text saying following lines
- may contain character constants, extra white space, comments, etc. */
-
-#define ASM_APP_ON ""
-
-/* Output to assembler file text saying following lines
- no longer contain unusual constructs. */
-
-#define ASM_APP_OFF ""
-
-/* We don't yet know how to identify GCC to HP-PA machines. */
-#define ASM_IDENTIFY_GCC(FILE) fputs ("; gcc_compiled.:\n", FILE)
-
-/* Output before code. */
-
-/* Supposedly the assembler rejects the command if there is no tab! */
-#define TEXT_SECTION_ASM_OP "\t.SPACE $TEXT$\n\t.SUBSPA $CODE$\n"
-
-/* Output before read-only data. */
-
-/* Supposedly the assembler rejects the command if there is no tab! */
-#define READONLY_DATA_ASM_OP "\t.SPACE $TEXT$\n\t.SUBSPA $LIT$\n"
-
-#define READONLY_DATA_SECTION readonly_data
-
-/* Output before writable data. */
-
-/* Supposedly the assembler rejects the command if there is no tab! */
-#define DATA_SECTION_ASM_OP "\t.SPACE $PRIVATE$\n\t.SUBSPA $DATA$\n"
-
-/* Output before uninitialized data. */
-
-#define BSS_SECTION_ASM_OP "\t.SPACE $PRIVATE$\n\t.SUBSPA $BSS$\n"
-
-/* Define the .bss section for ASM_OUTPUT_LOCAL to use. */
-
-#ifndef CTORS_SECTION_FUNCTION
-#define EXTRA_SECTIONS in_readonly_data
-#define CTORS_SECTION_FUNCTION
-#define DTORS_SECTION_FUNCTION
-#else
-#define EXTRA_SECTIONS in_readonly_data, in_ctors, in_dtors
-#endif
-
-/* Switch into a generic section.
- This is currently only used to support section attributes.
-
- We make the section read-only and executable for a function decl,
- read-only for a const data decl, and writable for a non-const data decl. */
-#define ASM_OUTPUT_SECTION_NAME(FILE, DECL, NAME, RELOC) \
- if (DECL && TREE_CODE (DECL) == FUNCTION_DECL) \
- { \
- fputs ("\t.SPACE $TEXT$\n", FILE); \
- fprintf (FILE, \
- "\t.SUBSPA %s%s%s,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY,SORT=24\n",\
- TARGET_GAS ? "" : "$", NAME, TARGET_GAS ? "" : "$"); \
- } \
- else if (DECL && DECL_READONLY_SECTION (DECL, RELOC)) \
- { \
- fputs ("\t.SPACE $TEXT$\n", FILE); \
- fprintf (FILE, \
- "\t.SUBSPA %s%s%s,QUAD=0,ALIGN=8,ACCESS=44,SORT=16\n", \
- TARGET_GAS ? "" : "$", NAME, TARGET_GAS ? "" : "$"); \
- } \
- else \
- { \
- fputs ("\t.SPACE $PRIVATE$\n", FILE); \
- fprintf (FILE, \
- "\t.SUBSPA %s%s%s,QUAD=1,ALIGN=8,ACCESS=31,SORT=16\n", \
- TARGET_GAS ? "" : "$", NAME, TARGET_GAS ? "" : "$"); \
- }
-
-/* FIXME: HPUX ld generates incorrect GOT entries for "T" fixups
- which reference data within the $TEXT$ space (for example constant
- strings in the $LIT$ subspace).
-
- The assemblers (GAS and HP as) both have problems with handling
- the difference of two symbols which is the other correct way to
- reference constant data during PIC code generation.
-
- So, there's no way to reference constant data which is in the
- $TEXT$ space during PIC generation. Instead place all constant
- data into the $PRIVATE$ subspace (this reduces sharing, but it
- works correctly). */
-
-#define EXTRA_SECTION_FUNCTIONS \
-void \
-readonly_data () \
-{ \
- if (in_section != in_readonly_data) \
- { \
- if (flag_pic) \
- fprintf (asm_out_file, "%s\n", DATA_SECTION_ASM_OP); \
- else \
- fprintf (asm_out_file, "%s\n", READONLY_DATA_ASM_OP); \
- in_section = in_readonly_data; \
- } \
-} \
-CTORS_SECTION_FUNCTION \
-DTORS_SECTION_FUNCTION
-
-
-/* How to refer to registers in assembler output.
- This sequence is indexed by compiler's hard-register-number (see above). */
-
-#define REGISTER_NAMES \
-{"%r0", "%r1", "%r2", "%r3", "%r4", "%r5", "%r6", "%r7", \
- "%r8", "%r9", "%r10", "%r11", "%r12", "%r13", "%r14", "%r15", \
- "%r16", "%r17", "%r18", "%r19", "%r20", "%r21", "%r22", "%r23", \
- "%r24", "%r25", "%r26", "%r27", "%r28", "%r29", "%r30", "%r31", \
- "%fr4", "%fr4R", "%fr5", "%fr5R", "%fr6", "%fr6R", "%fr7", "%fr7R", \
- "%fr8", "%fr8R", "%fr9", "%fr9R", "%fr10", "%fr10R", "%fr11", "%fr11R", \
- "%fr12", "%fr12R", "%fr13", "%fr13R", "%fr14", "%fr14R", "%fr15", "%fr15R", \
- "%fr16", "%fr16R", "%fr17", "%fr17R", "%fr18", "%fr18R", "%fr19", "%fr19R", \
- "%fr20", "%fr20R", "%fr21", "%fr21R", "%fr22", "%fr22R", "%fr23", "%fr23R", \
- "%fr24", "%fr24R", "%fr25", "%fr25R", "%fr26", "%fr26R", "%fr27", "%fr27R", \
- "%fr28", "%fr28R", "%fr29", "%fr29R", "%fr30", "%fr30R", "%fr31", "%fr31R", \
- "SAR"}
-
-#define ADDITIONAL_REGISTER_NAMES \
-{{"%fr4L",32}, {"%fr5L",34}, {"%fr6L",36}, {"%fr7L",38}, \
- {"%fr8L",40}, {"%fr9L",42}, {"%fr10L",44}, {"%fr11L",46}, \
- {"%fr12L",48}, {"%fr13L",50}, {"%fr14L",52}, {"%fr15L",54}, \
- {"%fr16L",56}, {"%fr17L",58}, {"%fr18L",60}, {"%fr19L",62}, \
- {"%fr20L",64}, {"%fr21L",66}, {"%fr22L",68}, {"%fr23L",70}, \
- {"%fr24L",72}, {"%fr25L",74}, {"%fr26L",76}, {"%fr27L",78}, \
- {"%fr28L",80}, {"%fr29L",82}, {"%fr30L",84}, {"%fr31R",86}, \
- {"%cr11",88}}
-
-/* How to renumber registers for dbx and gdb.
-
- Registers 0 - 31 remain unchanged.
-
- Registers 32 - 87 are mapped to 72 - 127
-
- Register 88 is mapped to 32. */
-
-#define DBX_REGISTER_NUMBER(REGNO) \
- ((REGNO) <= 31 ? (REGNO) : \
- ((REGNO) > 31 && (REGNO) <= 87 ? (REGNO) + 40 : 32))
-
-/* This is how to output the definition of a user-level label named NAME,
- such as the label on a static function or variable NAME. */
-
-#define ASM_OUTPUT_LABEL(FILE, NAME) \
- do { assemble_name (FILE, NAME); \
- fputc ('\n', FILE); } while (0)
-
-/* This is how to output a command to make the user-level label named NAME
- defined for reference from other files.
-
- We call assemble_name, which in turn sets TREE_SYMBOL_REFERENCED. This
- macro will restore the original value of TREE_SYMBOL_REFERENCED to avoid
- placing useless function definitions in the output file. */
-
-#define ASM_OUTPUT_EXTERNAL(FILE, DECL, NAME) \
- do { int save_referenced; \
- save_referenced = TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (DECL)); \
- fputs ("\t.IMPORT ", FILE); \
- assemble_name (FILE, NAME); \
- if (FUNCTION_NAME_P (NAME)) \
- fputs (",CODE\n", FILE); \
- else \
- fputs (",DATA\n", FILE); \
- TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (DECL)) = save_referenced; \
- } while (0)
-
-/* The bogus HP assembler requires ALL external references to be
- "imported", even library calls. They look a bit different, so
- here's this macro.
-
- Also note not all libcall names are passed to ENCODE_SECTION_INFO
- (__main for example). To make sure all libcall names have section
- info recorded in them, we do it here. */
-
-#define ASM_OUTPUT_EXTERNAL_LIBCALL(FILE, RTL) \
- do { fputs ("\t.IMPORT ", FILE); \
- if (!function_label_operand (RTL, VOIDmode)) \
- hppa_encode_label (RTL, 1); \
- assemble_name (FILE, XSTR ((RTL), 0)); \
- fputs (",CODE\n", FILE); \
- } while (0)
-
-#define ASM_GLOBALIZE_LABEL(FILE, NAME) \
- do { \
- /* We only handle DATA objects here, functions are globalized in \
- ASM_DECLARE_FUNCTION_NAME. */ \
- if (! FUNCTION_NAME_P (NAME)) \
- { \
- fputs ("\t.EXPORT ", FILE); \
- assemble_name (FILE, NAME); \
- fputs (",DATA\n", FILE); \
- } \
- } while (0)
-
-/* This is how to output a reference to a user-level label named NAME.
- `assemble_name' uses this. */
-
-#define ASM_OUTPUT_LABELREF(FILE,NAME) \
- fprintf ((FILE), "%s", (NAME) + (FUNCTION_NAME_P (NAME) ? 1 : 0))
-
-/* This is how to output an internal numbered label where
- PREFIX is the class of label and NUM is the number within the class. */
-
-#define ASM_OUTPUT_INTERNAL_LABEL(FILE,PREFIX,NUM) \
- {fprintf (FILE, "%c$%s%04d\n", (PREFIX)[0], (PREFIX) + 1, NUM);}
-
-/* This is how to store into the string LABEL
- the symbol_ref name of an internal numbered label where
- PREFIX is the class of label and NUM is the number within the class.
- This is suitable for output with `assemble_name'. */
-
-#define ASM_GENERATE_INTERNAL_LABEL(LABEL,PREFIX,NUM) \
- sprintf (LABEL, "*%c$%s%04d", (PREFIX)[0], (PREFIX) + 1, NUM)
-
-/* This is how to output an assembler line defining a `double' constant. */
-
-#define ASM_OUTPUT_DOUBLE(FILE,VALUE) \
- do { long l[2]; \
- REAL_VALUE_TO_TARGET_DOUBLE (VALUE, l); \
- fprintf (FILE, "\t.word 0x%lx\n\t.word 0x%lx\n", l[0], l[1]); \
- } while (0)
-
-/* This is how to output an assembler line defining a `float' constant. */
-
-#define ASM_OUTPUT_FLOAT(FILE,VALUE) \
- do { long l; \
- REAL_VALUE_TO_TARGET_SINGLE (VALUE, l); \
- fprintf (FILE, "\t.word 0x%lx\n", l); \
- } while (0)
-
-/* This is how to output an assembler line defining an `int' constant.
-
- This is made more complicated by the fact that functions must be
- prefixed by a P% as well as code label references for the exception
- table -- otherwise the linker chokes. */
-
-#define ASM_OUTPUT_INT(FILE,VALUE) \
-{ fputs ("\t.word ", FILE); \
- if (function_label_operand (VALUE, VOIDmode) \
- && !TARGET_PORTABLE_RUNTIME) \
- fputs ("P%", FILE); \
- output_addr_const (FILE, (VALUE)); \
- fputs ("\n", FILE);}
-
-/* Likewise for `short' and `char' constants. */
-
-#define ASM_OUTPUT_SHORT(FILE,VALUE) \
-( fputs ("\t.half ", FILE), \
- output_addr_const (FILE, (VALUE)), \
- fputs ("\n", FILE))
-
-#define ASM_OUTPUT_CHAR(FILE,VALUE) \
-( fputs ("\t.byte ", FILE), \
- output_addr_const (FILE, (VALUE)), \
- fputs ("\n", FILE))
-
-/* This is how to output an assembler line for a numeric constant byte. */
-
-#define ASM_OUTPUT_BYTE(FILE,VALUE) \
- fprintf (FILE, "\t.byte 0x%x\n", (VALUE))
-
-#define ASM_OUTPUT_ASCII(FILE, P, SIZE) \
- output_ascii ((FILE), (P), (SIZE))
-
-#define ASM_OUTPUT_REG_PUSH(FILE,REGNO)
-#define ASM_OUTPUT_REG_POP(FILE,REGNO)
-/* This is how to output an element of a case-vector that is absolute.
- Note that this method makes filling these branch delay slots
- impossible. */
-
-#define ASM_OUTPUT_ADDR_VEC_ELT(FILE, VALUE) \
- if (TARGET_BIG_SWITCH) \
- fprintf (FILE, "\tstw %%r1,-16(%%r30)\n\tldil LR'L$%04d,%%r1\n\tbe RR'L$%04d(%%sr4,%%r1)\n\tldw -16(%%r30),%%r1\n", VALUE, VALUE); \
- else \
- fprintf (FILE, "\tb L$%04d\n\tnop\n", VALUE)
-
-/* Jump tables are executable code and live in the TEXT section on the PA. */
-#define JUMP_TABLES_IN_TEXT_SECTION 1
-
-/* This is how to output an element of a case-vector that is relative.
- This must be defined correctly as it is used when generating PIC code.
-
- I believe it safe to use the same definition as ASM_OUTPUT_ADDR_VEC_ELT
- on the PA since ASM_OUTPUT_ADDR_VEC_ELT uses pc-relative jump instructions
- rather than a table of absolute addresses. */
-
-#define ASM_OUTPUT_ADDR_DIFF_ELT(FILE, BODY, VALUE, REL) \
- if (TARGET_BIG_SWITCH) \
- fprintf (FILE, "\tstw %%r1,-16(%%r30)\n\tldw T'L$%04d(%%r19),%%r1\n\tbv 0(%%r1)\n\tldw -16(%%r30),%%r1\n", VALUE); \
- else \
- fprintf (FILE, "\tb L$%04d\n\tnop\n", VALUE)
-
-/* This is how to output an assembler line
- that says to advance the location counter
- to a multiple of 2**LOG bytes. */
-
-#define ASM_OUTPUT_ALIGN(FILE,LOG) \
- fprintf (FILE, "\t.align %d\n", (1<<(LOG)))
-
-#define ASM_OUTPUT_SKIP(FILE,SIZE) \
- fprintf (FILE, "\t.blockz %d\n", (SIZE))
-
-/* This says how to output an assembler line to define a global common symbol
- with size SIZE (in bytes) and alignment ALIGN (in bits). */
-
-#define ASM_OUTPUT_ALIGNED_COMMON(FILE, NAME, SIZE, ALIGNED) \
-{ bss_section (); \
- assemble_name ((FILE), (NAME)); \
- fputs ("\t.comm ", (FILE)); \
- fprintf ((FILE), "%d\n", MAX ((SIZE), ((ALIGNED) / BITS_PER_UNIT)));}
-
-/* This says how to output an assembler line to define a local common symbol
- with size SIZE (in bytes) and alignment ALIGN (in bits). */
-
-#define ASM_OUTPUT_ALIGNED_LOCAL(FILE, NAME, SIZE, ALIGNED) \
-{ bss_section (); \
- fprintf ((FILE), "\t.align %d\n", ((ALIGNED) / BITS_PER_UNIT)); \
- assemble_name ((FILE), (NAME)); \
- fprintf ((FILE), "\n\t.block %d\n", (SIZE));}
-
-/* Store in OUTPUT a string (made with alloca) containing
- an assembler-name for a local static variable named NAME.
- LABELNO is an integer which is different for each call. */
-
-#define ASM_FORMAT_PRIVATE_NAME(OUTPUT, NAME, LABELNO) \
-( (OUTPUT) = (char *) alloca (strlen ((NAME)) + 12), \
- sprintf ((OUTPUT), "%s___%d", (NAME), (LABELNO)))
-
-/* Define the parentheses used to group arithmetic operations
- in assembler code. */
-
-#define ASM_OPEN_PAREN "("
-#define ASM_CLOSE_PAREN ")"
-
-/* All HP assemblers use "!" to separate logical lines. */
-#define IS_ASM_LOGICAL_LINE_SEPARATOR(C) ((C) == '!')
-
-/* Define results of standard character escape sequences. */
-#define TARGET_BELL 007
-#define TARGET_BS 010
-#define TARGET_TAB 011
-#define TARGET_NEWLINE 012
-#define TARGET_VT 013
-#define TARGET_FF 014
-#define TARGET_CR 015
-
-#define PRINT_OPERAND_PUNCT_VALID_P(CHAR) \
- ((CHAR) == '@' || (CHAR) == '#' || (CHAR) == '*' || (CHAR) == '^')
-
-/* Print operand X (an rtx) in assembler syntax to file FILE.
- CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
- For `%' followed by punctuation, CODE is the punctuation and X is null.
-
- On the HP-PA, the CODE can be `r', meaning this is a register-only operand
- and an immediate zero should be represented as `r0'.
-
- Several % codes are defined:
- O an operation
- C compare conditions
- N extract conditions
- M modifier to handle preincrement addressing for memory refs.
- F modifier to handle preincrement addressing for fp memory refs */
-
-#define PRINT_OPERAND(FILE, X, CODE) print_operand (FILE, X, CODE)
-
-
-/* Print a memory address as an operand to reference that memory location. */
-
-#define PRINT_OPERAND_ADDRESS(FILE, ADDR) \
-{ register rtx addr = ADDR; \
- register rtx base; \
- int offset; \
- switch (GET_CODE (addr)) \
- { \
- case REG: \
- fprintf (FILE, "0(0,%s)", reg_names [REGNO (addr)]); \
- break; \
- case PLUS: \
- if (GET_CODE (XEXP (addr, 0)) == CONST_INT) \
- offset = INTVAL (XEXP (addr, 0)), base = XEXP (addr, 1); \
- else if (GET_CODE (XEXP (addr, 1)) == CONST_INT) \
- offset = INTVAL (XEXP (addr, 1)), base = XEXP (addr, 0); \
- else \
- abort (); \
- fprintf (FILE, "%d(0,%s)", offset, reg_names [REGNO (base)]); \
- break; \
- case LO_SUM: \
- if (!symbolic_operand (XEXP (addr, 1))) \
- fputs ("R'", FILE); \
- else if (flag_pic == 0) \
- fputs ("RR'", FILE); \
- else if (flag_pic == 1) \
- abort (); \
- else if (flag_pic == 2) \
- fputs ("RT'", FILE); \
- output_global_address (FILE, XEXP (addr, 1), 0); \
- fputs ("(", FILE); \
- output_operand (XEXP (addr, 0), 0); \
- fputs (")", FILE); \
- break; \
- case CONST_INT: \
- fprintf (FILE, "%d(0,0)", INTVAL (addr)); \
- break; \
- default: \
- output_addr_const (FILE, addr); \
- }}
-
-
-/* Define functions in pa.c and used in insn-output.c. */
-
-extern char *output_and ();
-extern char *output_ior ();
-extern char *output_move_double ();
-extern char *output_fp_move_double ();
-extern char *output_block_move ();
-extern char *output_cbranch ();
-extern char *output_bb ();
-extern char *output_bvb ();
-extern char *output_dbra ();
-extern char *output_movb ();
-extern char *output_parallel_movb ();
-extern char *output_parallel_addb ();
-extern char *output_return ();
-extern char *output_call ();
-extern char *output_millicode_call ();
-extern char *output_mul_insn ();
-extern char *output_div_insn ();
-extern char *output_mod_insn ();
-extern char *singlemove_string ();
-extern void output_arg_descriptor ();
-extern void output_deferred_plabels ();
-extern void override_options ();
-extern void output_ascii ();
-extern void output_function_prologue ();
-extern void output_function_epilogue ();
-extern void output_global_address ();
-extern void print_operand ();
-extern struct rtx_def *legitimize_pic_address ();
-extern struct rtx_def *gen_cmp_fp ();
-extern void hppa_encode_label ();
-extern int arith11_operand ();
-extern int symbolic_expression_p ();
-extern int reloc_needed ();
-extern int compute_frame_size ();
-extern int hppa_address_cost ();
-extern int and_mask_p ();
-extern int symbolic_memory_operand ();
-extern int pa_adjust_cost ();
-extern int pa_adjust_insn_length ();
-extern int int11_operand ();
-extern int reg_or_cint_move_operand ();
-extern int arith5_operand ();
-extern int uint5_operand ();
-extern int pic_label_operand ();
-extern int plus_xor_ior_operator ();
-extern int basereg_operand ();
-extern int shadd_operand ();
-extern int arith_operand ();
-extern int read_only_operand ();
-extern int move_operand ();
-extern int and_operand ();
-extern int ior_operand ();
-extern int arith32_operand ();
-extern int uint32_operand ();
-extern int reg_or_nonsymb_mem_operand ();
-extern int reg_or_0_operand ();
-extern int reg_or_0_or_nonsymb_mem_operand ();
-extern int pre_cint_operand ();
-extern int post_cint_operand ();
-extern int div_operand ();
-extern int int5_operand ();
-extern int movb_comparison_operator ();
-extern int ireg_or_int5_operand ();
-extern int fmpyaddoperands ();
-extern int fmpysuboperands ();
-extern int call_operand_address ();
-extern int cint_ok_for_move ();
-extern int ior_operand ();
-extern void emit_bcond_fp ();
-extern int emit_move_sequence ();
-extern int emit_hpdiv_const ();
-extern void hppa_expand_prologue ();
-extern void hppa_expand_epilogue ();
-extern int hppa_can_use_return_insn_p ();
-extern int is_function_label_plus_const ();
-extern int jump_in_call_delay ();
-extern enum reg_class secondary_reload_class ();
-extern int insn_sets_and_refs_are_delayed ();
-
-/* Declare functions defined in pa.c and used in templates. */
-
-extern struct rtx_def *return_addr_rtx ();
-
-/* We want __gcc_plt_call to appear in every program built by
- gcc, so we make a reference to it out of __main.
- We use the asm statement to fool the optimizer into not
- removing the dead (but important) initialization of
- REFERENCE. */
-
-#define DO_GLOBAL_DTORS_BODY \
-do { \
- extern void __gcc_plt_call (); \
- void (*reference)() = &__gcc_plt_call; \
- func_ptr *p; \
- __asm__ ("" : : "r" (reference)); \
- for (p = __DTOR_LIST__ + 1; *p; ) \
- (*p++) (); \
-} while (0)
-
-/* Find the return address associated with the frame given by
- FRAMEADDR. */
-#define RETURN_ADDR_RTX(COUNT, FRAMEADDR) \
- (return_addr_rtx (COUNT, FRAMEADDR))
-
-/* Used to mask out junk bits from the return address, such as
- processor state, interrupt status, condition codes and the like. */
-#define MASK_RETURN_ADDR \
- /* The privilege level is in the two low order bits, mask em out \
- of the return address. */ \
- (GEN_INT (0xfffffffc))
-
-/* The number of Pmode words for the setjmp buffer. */
-#define JMP_BUF_SIZE 50
diff --git a/gcc/config/pa/pa.md b/gcc/config/pa/pa.md
deleted file mode 100755
index 174bbd7..0000000
--- a/gcc/config/pa/pa.md
+++ /dev/null
@@ -1,5729 +0,0 @@
-;;- Machine description for HP PA-RISC architecture for GNU C compiler
-;; Copyright (C) 1992, 93-98, 1999 Free Software Foundation, Inc.
-;; Contributed by the Center for Software Science at the University
-;; of Utah.
-
-;; This file is part of GNU CC.
-
-;; GNU CC is free software; you can redistribute it and/or modify
-;; it under the terms of the GNU General Public License as published by
-;; the Free Software Foundation; either version 2, or (at your option)
-;; any later version.
-
-;; GNU CC is distributed in the hope that it will be useful,
-;; but WITHOUT ANY WARRANTY; without even the implied warranty of
-;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-;; GNU General Public License for more details.
-
-;; You should have received a copy of the GNU General Public License
-;; along with GNU CC; see the file COPYING. If not, write to
-;; the Free Software Foundation, 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
-
-;; This gcc Version 2 machine description is inspired by sparc.md and
-;; mips.md.
-
-;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
-
-;; Insn type. Used to default other attribute values.
-
-;; type "unary" insns have one input operand (1) and one output operand (0)
-;; type "binary" insns have two input operands (1,2) and one output (0)
-
-(define_attr "type"
- "move,unary,binary,shift,nullshift,compare,load,store,uncond_branch,branch,cbranch,fbranch,call,dyncall,fpload,fpstore,fpalu,fpcc,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,multi,milli,parallel_branch"
- (const_string "binary"))
-
-(define_attr "pa_combine_type"
- "fmpy,faddsub,uncond_branch,addmove,none"
- (const_string "none"))
-
-;; Processor type (for scheduling, not code generation) -- this attribute
-;; must exactly match the processor_type enumeration in pa.h.
-;;
-;; FIXME: Add 800 scheduling for completeness?
-
-;; CYGNUS LOCAL PA8000/law
-(define_attr "cpu" "700,7100,7100LC,7200,8000" (const (symbol_ref "pa_cpu_attr")))
-;; END CYGNUS LOCAL
-
-;; Length (in # of insns).
-(define_attr "length" ""
- (cond [(eq_attr "type" "load,fpload")
- (if_then_else (match_operand 1 "symbolic_memory_operand" "")
- (const_int 8) (const_int 4))
-
- (eq_attr "type" "store,fpstore")
- (if_then_else (match_operand 0 "symbolic_memory_operand" "")
- (const_int 8) (const_int 4))
-
- (eq_attr "type" "binary,shift,nullshift")
- (if_then_else (match_operand 2 "arith_operand" "")
- (const_int 4) (const_int 12))
-
- (eq_attr "type" "move,unary,shift,nullshift")
- (if_then_else (match_operand 1 "arith_operand" "")
- (const_int 4) (const_int 8))]
-
- (const_int 4)))
-
-(define_asm_attributes
- [(set_attr "length" "4")
- (set_attr "type" "multi")])
-
-;; Attributes for instruction and branch scheduling
-
-;; For conditional branches.
-(define_attr "in_branch_delay" "false,true"
- (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,parallel_branch")
- (eq_attr "length" "4"))
- (const_string "true")
- (const_string "false")))
-
-;; Disallow instructions which use the FPU since they will tie up the FPU
-;; even if the instruction is nullified.
-(define_attr "in_nullified_branch_delay" "false,true"
- (if_then_else (and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpdivdbl,fpsqrtsgl,fpsqrtdbl,parallel_branch")
- (eq_attr "length" "4"))
- (const_string "true")
- (const_string "false")))
-
-;; For calls and millicode calls. Allow unconditional branches in the
-;; delay slot.
-(define_attr "in_call_delay" "false,true"
- (cond [(and (eq_attr "type" "!uncond_branch,branch,cbranch,fbranch,call,dyncall,multi,milli,parallel_branch")
- (eq_attr "length" "4"))
- (const_string "true")
- (eq_attr "type" "uncond_branch")
- (if_then_else (ne (symbol_ref "TARGET_JUMP_IN_DELAY")
- (const_int 0))
- (const_string "true")
- (const_string "false"))]
- (const_string "false")))
-
-
-;; Call delay slot description.
-(define_delay (eq_attr "type" "call")
- [(eq_attr "in_call_delay" "true") (nil) (nil)])
-
-;; millicode call delay slot description. Note it disallows delay slot
-;; when TARGET_PORTABLE_RUNTIME is true.
-(define_delay (eq_attr "type" "milli")
- [(and (eq_attr "in_call_delay" "true")
- (eq (symbol_ref "TARGET_PORTABLE_RUNTIME") (const_int 0)))
- (nil) (nil)])
-
-;; Return and other similar instructions.
-(define_delay (eq_attr "type" "branch,parallel_branch")
- [(eq_attr "in_branch_delay" "true") (nil) (nil)])
-
-;; Floating point conditional branch delay slot description and
-(define_delay (eq_attr "type" "fbranch")
- [(eq_attr "in_branch_delay" "true")
- (eq_attr "in_nullified_branch_delay" "true")
- (nil)])
-
-;; Integer conditional branch delay slot description.
-;; Nullification of conditional branches on the PA is dependent on the
-;; direction of the branch. Forward branches nullify true and
-;; backward branches nullify false. If the direction is unknown
-;; then nullification is not allowed.
-(define_delay (eq_attr "type" "cbranch")
- [(eq_attr "in_branch_delay" "true")
- (and (eq_attr "in_nullified_branch_delay" "true")
- (attr_flag "forward"))
- (and (eq_attr "in_nullified_branch_delay" "true")
- (attr_flag "backward"))])
-
-(define_delay (and (eq_attr "type" "uncond_branch")
- (eq (symbol_ref "following_call (insn)")
- (const_int 0)))
- [(eq_attr "in_branch_delay" "true") (nil) (nil)])
-
-;; Function units of the HPPA. The following data is for the 700 CPUs
-;; (Mustang CPU + Timex FPU aka PA-89) because that's what I have the docs for.
-;; Scheduling instructions for PA-83 machines according to the Snake
-;; constraints shouldn't hurt.
-
-;; (define_function_unit {name} {num-units} {n-users} {test}
-;; {ready-delay} {issue-delay} [{conflict-list}])
-
-;; The integer ALU.
-;; (Noted only for documentation; units that take one cycle do not need to
-;; be specified.)
-
-;; (define_function_unit "alu" 1 0
-;; (and (eq_attr "type" "unary,shift,nullshift,binary,move,address")
-;; (eq_attr "cpu" "700"))
-;; 1 0)
-
-
-;; Memory. Disregarding Cache misses, the Mustang memory times are:
-;; load: 2, fpload: 3
-;; store, fpstore: 3, no D-cache operations should be scheduled.
-
-(define_function_unit "pa700memory" 1 0
- (and (eq_attr "type" "load,fpload")
- (eq_attr "cpu" "700")) 2 0)
-(define_function_unit "pa700memory" 1 0
- (and (eq_attr "type" "store,fpstore")
- (eq_attr "cpu" "700")) 3 3)
-
-;; The Timex (aka 700) has two floating-point units: ALU, and MUL/DIV/SQRT.
-;; Timings:
-;; Instruction Time Unit Minimum Distance (unit contention)
-;; fcpy 3 ALU 2
-;; fabs 3 ALU 2
-;; fadd 3 ALU 2
-;; fsub 3 ALU 2
-;; fcmp 3 ALU 2
-;; fcnv 3 ALU 2
-;; fmpyadd 3 ALU,MPY 2
-;; fmpysub 3 ALU,MPY 2
-;; fmpycfxt 3 ALU,MPY 2
-;; fmpy 3 MPY 2
-;; fmpyi 3 MPY 2
-;; fdiv,sgl 10 MPY 10
-;; fdiv,dbl 12 MPY 12
-;; fsqrt,sgl 14 MPY 14
-;; fsqrt,dbl 18 MPY 18
-
-(define_function_unit "pa700fp_alu" 1 0
- (and (eq_attr "type" "fpcc")
- (eq_attr "cpu" "700")) 4 2)
-(define_function_unit "pa700fp_alu" 1 0
- (and (eq_attr "type" "fpalu")
- (eq_attr "cpu" "700")) 3 2)
-(define_function_unit "pa700fp_mpy" 1 0
- (and (eq_attr "type" "fpmulsgl,fpmuldbl")
- (eq_attr "cpu" "700")) 3 2)
-(define_function_unit "pa700fp_mpy" 1 0
- (and (eq_attr "type" "fpdivsgl")
- (eq_attr "cpu" "700")) 10 10)
-(define_function_unit "pa700fp_mpy" 1 0
- (and (eq_attr "type" "fpdivdbl")
- (eq_attr "cpu" "700")) 12 12)
-(define_function_unit "pa700fp_mpy" 1 0
- (and (eq_attr "type" "fpsqrtsgl")
- (eq_attr "cpu" "700")) 14 14)
-(define_function_unit "pa700fp_mpy" 1 0
- (and (eq_attr "type" "fpsqrtdbl")
- (eq_attr "cpu" "700")) 18 18)
-
-;; Function units for the 7100 and 7150. The 7100/7150 can dual-issue
-;; floating point computations with non-floating point computations (fp loads
-;; and stores are not fp computations).
-;;
-
-;; Memory. Disregarding Cache misses, memory loads take two cycles; stores also
-;; take two cycles, during which no Dcache operations should be scheduled.
-;; Any special cases are handled in pa_adjust_cost. The 7100, 7150 and 7100LC
-;; all have the same memory characteristics if one disregards cache misses.
-(define_function_unit "pa7100memory" 1 0
- (and (eq_attr "type" "load,fpload")
- (eq_attr "cpu" "7100,7100LC")) 2 0)
-(define_function_unit "pa7100memory" 1 0
- (and (eq_attr "type" "store,fpstore")
- (eq_attr "cpu" "7100,7100LC")) 2 2)
-
-;; The 7100/7150 has three floating-point units: ALU, MUL, and DIV.
-;; Timings:
-;; Instruction Time Unit Minimum Distance (unit contention)
-;; fcpy 2 ALU 1
-;; fabs 2 ALU 1
-;; fadd 2 ALU 1
-;; fsub 2 ALU 1
-;; fcmp 2 ALU 1
-;; fcnv 2 ALU 1
-;; fmpyadd 2 ALU,MPY 1
-;; fmpysub 2 ALU,MPY 1
-;; fmpycfxt 2 ALU,MPY 1
-;; fmpy 2 MPY 1
-;; fmpyi 2 MPY 1
-;; fdiv,sgl 8 DIV 8
-;; fdiv,dbl 15 DIV 15
-;; fsqrt,sgl 8 DIV 8
-;; fsqrt,dbl 15 DIV 15
-
-(define_function_unit "pa7100fp_alu" 1 0
- (and (eq_attr "type" "fpcc,fpalu")
- (eq_attr "cpu" "7100")) 2 1)
-(define_function_unit "pa7100fp_mpy" 1 0
- (and (eq_attr "type" "fpmulsgl,fpmuldbl")
- (eq_attr "cpu" "7100")) 2 1)
-(define_function_unit "pa7100fp_div" 1 0
- (and (eq_attr "type" "fpdivsgl,fpsqrtsgl")
- (eq_attr "cpu" "7100")) 8 8)
-(define_function_unit "pa7100fp_div" 1 0
- (and (eq_attr "type" "fpdivdbl,fpsqrtdbl")
- (eq_attr "cpu" "7100")) 15 15)
-
-;; To encourage dual issue we define function units corresponding to
-;; the instructions which can be dual issued. This is a rather crude
-;; approximation, the "pa7100nonflop" test in particular could be refined.
-(define_function_unit "pa7100flop" 1 1
- (and
- (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl")
- (eq_attr "cpu" "7100")) 1 1)
-
-(define_function_unit "pa7100nonflop" 1 1
- (and
- (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl")
- (eq_attr "cpu" "7100")) 1 1)
-
-
-;; Memory subsystem works just like 7100/7150 (except for cache miss times which
-;; we don't model here).
-
-;; The 7100LC has three floating-point units: ALU, MUL, and DIV.
-;; Note divides and sqrt flops lock the cpu until the flop is
-;; finished. fmpy and xmpyu (fmpyi) lock the cpu for one cycle.
-;; There's no way to avoid the penalty.
-;; Timings:
-;; Instruction Time Unit Minimum Distance (unit contention)
-;; fcpy 2 ALU 1
-;; fabs 2 ALU 1
-;; fadd 2 ALU 1
-;; fsub 2 ALU 1
-;; fcmp 2 ALU 1
-;; fcnv 2 ALU 1
-;; fmpyadd,sgl 2 ALU,MPY 1
-;; fmpyadd,dbl 3 ALU,MPY 2
-;; fmpysub,sgl 2 ALU,MPY 1
-;; fmpysub,dbl 3 ALU,MPY 2
-;; fmpycfxt,sgl 2 ALU,MPY 1
-;; fmpycfxt,dbl 3 ALU,MPY 2
-;; fmpy,sgl 2 MPY 1
-;; fmpy,dbl 3 MPY 2
-;; fmpyi 3 MPY 2
-;; fdiv,sgl 8 DIV 8
-;; fdiv,dbl 15 DIV 15
-;; fsqrt,sgl 8 DIV 8
-;; fsqrt,dbl 15 DIV 15
-
-(define_function_unit "pa7100LCfp_alu" 1 0
- (and (eq_attr "type" "fpcc,fpalu")
- (eq_attr "cpu" "7100LC,7200")) 2 1)
-(define_function_unit "pa7100LCfp_mpy" 1 0
- (and (eq_attr "type" "fpmulsgl")
- (eq_attr "cpu" "7100LC,7200")) 2 1)
-(define_function_unit "pa7100LCfp_mpy" 1 0
- (and (eq_attr "type" "fpmuldbl")
- (eq_attr "cpu" "7100LC,7200")) 3 2)
-(define_function_unit "pa7100LCfp_div" 1 0
- (and (eq_attr "type" "fpdivsgl,fpsqrtsgl")
- (eq_attr "cpu" "7100LC,7200")) 8 8)
-(define_function_unit "pa7100LCfp_div" 1 0
- (and (eq_attr "type" "fpdivdbl,fpsqrtdbl")
- (eq_attr "cpu" "7100LC,7200")) 15 15)
-
-;; Define the various functional units for dual-issue.
-
-;; There's only one floating point unit.
-(define_function_unit "pa7100LCflop" 1 1
- (and
- (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl")
- (eq_attr "cpu" "7100LC,7200")) 1 1)
-
-;; Shifts and memory ops actually execute in one of the integer
-;; ALUs, but we can't really model that.
-(define_function_unit "pa7100LCshiftmem" 1 1
- (and
- (eq_attr "type" "shift,nullshift,load,fpload,store,fpstore")
- (eq_attr "cpu" "7100LC,7200")) 1 1)
-
-;; We have two basic ALUs.
-(define_function_unit "pa7100LCalu" 2 2
- (and
- (eq_attr "type" "!fpcc,fpalu,fpmulsgl,fpmuldbl,fpdivsgl,fpsqrtsgl,fpdivdbl,fpsqrtdbl,load,fpload,store,fpstore,shift,nullshift")
- (eq_attr "cpu" "7100LC,7200")) 1 1)
-
-;; I don't have complete information on the PA7200; however, most of
-;; what I've heard makes it look like a 7100LC without the store-store
-;; penalty. So that's how we'll model it.
-
-;; Memory. Disregarding Cache misses, memory loads and stores take
-;; two cycles. Any special cases are handled in pa_adjust_cost.
-(define_function_unit "pa7200memory" 1 0
- (and (eq_attr "type" "load,fpload,store,fpstore")
- (eq_attr "cpu" "7200")) 2 0)
-
-;; I don't have detailed information on the PA7200 FP pipeline, so I
-;; treat it just like the 7100LC pipeline.
-;; Similarly for the multi-issue fake units.
-
-;; CYGNUS LOCAL PA8000/law
-;;
-;; Scheduling for the PA8000 is somewhat different than scheduling for a
-;; traditional architecture.
-;;
-;; The PA8000 has a large (56) entry reorder buffer that is split between
-;; memory and non-memory operations.
-;;
-;; The PA800 can issue two memory and two non-memory operations per cycle to
-;; the function units. Similarly, the PA8000 can retire two memory and two
-;; non-memory operations per cycle.
-;;
-;; Given the large reorder buffer, the processor can hide most latencies.
-;; According to HP, they've got the best results by scheduling for retirement
-;; bandwidth with limited latency scheduling for floating point operations.
-;; Latency for integer operations and memory references is ignored.
-;;
-;; We claim floating point operations have a 2 cycle latency and are
-;; fully pipelined, except for div and sqrt which are not pipelined.
-;;
-;; It is not necessary to define the shifter and integer alu units.
-;;
-;; These first two define_unit_unit descriptions model retirement from
-;; the reorder buffer.
-(define_function_unit "pa8000lsu" 2 2
- (and
- (eq_attr "type" "load,fpload,store,fpstore")
- (eq_attr "cpu" "8000")) 1 0)
-
-(define_function_unit "pa8000alu" 2 2
- (and
- (eq_attr "type" "!load,fpload,store,fpstore")
- (eq_attr "cpu" "8000")) 1 0)
-
-;; Claim floating point ops have a 2 cycle latency, including div and
-;; sqrt, but div and sqrt are not pipelined and issue to different units.
-(define_function_unit "pa8000fmac" 2 0
- (and
- (eq_attr "type" "fpcc,fpalu,fpmulsgl,fpmuldbl")
- (eq_attr "cpu" "8000")) 2 0)
-
-(define_function_unit "pa8000fdiv" 2 2
- (and
- (eq_attr "type" "fpdivsgl,fpsqrtsgl")
- (eq_attr "cpu" "8000")) 17 17)
-
-(define_function_unit "pa8000fdiv" 2 2
- (and
- (eq_attr "type" "fpdivdbl,fpsqrtdbl")
- (eq_attr "cpu" "8000")) 31 31)
-;; END CYGNUS LOCAL
-
-;; Compare instructions.
-;; This controls RTL generation and register allocation.
-
-;; We generate RTL for comparisons and branches by having the cmpxx
-;; patterns store away the operands. Then, the scc and bcc patterns
-;; emit RTL for both the compare and the branch.
-;;
-
-(define_expand "cmpsi"
- [(set (reg:CC 0)
- (compare:CC (match_operand:SI 0 "reg_or_0_operand" "")
- (match_operand:SI 1 "arith5_operand" "")))]
- ""
- "
-{
- hppa_compare_op0 = operands[0];
- hppa_compare_op1 = operands[1];
- hppa_branch_type = CMP_SI;
- DONE;
-}")
-
-(define_expand "cmpsf"
- [(set (reg:CCFP 0)
- (compare:CCFP (match_operand:SF 0 "reg_or_0_operand" "")
- (match_operand:SF 1 "reg_or_0_operand" "")))]
- "! TARGET_SOFT_FLOAT"
- "
-{
- hppa_compare_op0 = operands[0];
- hppa_compare_op1 = operands[1];
- hppa_branch_type = CMP_SF;
- DONE;
-}")
-
-(define_expand "cmpdf"
- [(set (reg:CCFP 0)
- (compare:CCFP (match_operand:DF 0 "reg_or_0_operand" "")
- (match_operand:DF 1 "reg_or_0_operand" "")))]
- "! TARGET_SOFT_FLOAT"
- "
-{
- hppa_compare_op0 = operands[0];
- hppa_compare_op1 = operands[1];
- hppa_branch_type = CMP_DF;
- DONE;
-}")
-
-(define_insn ""
- [(set (reg:CCFP 0)
- (match_operator:CCFP 2 "comparison_operator"
- [(match_operand:SF 0 "reg_or_0_operand" "fG")
- (match_operand:SF 1 "reg_or_0_operand" "fG")]))]
- "! TARGET_SOFT_FLOAT"
- "fcmp,sgl,%Y2 %r0,%r1"
- [(set_attr "length" "4")
- (set_attr "type" "fpcc")])
-
-(define_insn ""
- [(set (reg:CCFP 0)
- (match_operator:CCFP 2 "comparison_operator"
- [(match_operand:DF 0 "reg_or_0_operand" "fG")
- (match_operand:DF 1 "reg_or_0_operand" "fG")]))]
- "! TARGET_SOFT_FLOAT"
- "fcmp,dbl,%Y2 %r0,%r1"
- [(set_attr "length" "4")
- (set_attr "type" "fpcc")])
-
-;; scc insns.
-
-(define_expand "seq"
- [(set (match_operand:SI 0 "register_operand" "")
- (eq:SI (match_dup 1)
- (match_dup 2)))]
- ""
- "
-{
- /* fp scc patterns rarely match, and are not a win on the PA. */
- if (hppa_branch_type != CMP_SI)
- FAIL;
- /* set up operands from compare. */
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
- /* fall through and generate default code */
-}")
-
-(define_expand "sne"
- [(set (match_operand:SI 0 "register_operand" "")
- (ne:SI (match_dup 1)
- (match_dup 2)))]
- ""
- "
-{
- /* fp scc patterns rarely match, and are not a win on the PA. */
- if (hppa_branch_type != CMP_SI)
- FAIL;
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
-}")
-
-(define_expand "slt"
- [(set (match_operand:SI 0 "register_operand" "")
- (lt:SI (match_dup 1)
- (match_dup 2)))]
- ""
- "
-{
- /* fp scc patterns rarely match, and are not a win on the PA. */
- if (hppa_branch_type != CMP_SI)
- FAIL;
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
-}")
-
-(define_expand "sgt"
- [(set (match_operand:SI 0 "register_operand" "")
- (gt:SI (match_dup 1)
- (match_dup 2)))]
- ""
- "
-{
- /* fp scc patterns rarely match, and are not a win on the PA. */
- if (hppa_branch_type != CMP_SI)
- FAIL;
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
-}")
-
-(define_expand "sle"
- [(set (match_operand:SI 0 "register_operand" "")
- (le:SI (match_dup 1)
- (match_dup 2)))]
- ""
- "
-{
- /* fp scc patterns rarely match, and are not a win on the PA. */
- if (hppa_branch_type != CMP_SI)
- FAIL;
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
-}")
-
-(define_expand "sge"
- [(set (match_operand:SI 0 "register_operand" "")
- (ge:SI (match_dup 1)
- (match_dup 2)))]
- ""
- "
-{
- /* fp scc patterns rarely match, and are not a win on the PA. */
- if (hppa_branch_type != CMP_SI)
- FAIL;
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
-}")
-
-(define_expand "sltu"
- [(set (match_operand:SI 0 "register_operand" "")
- (ltu:SI (match_dup 1)
- (match_dup 2)))]
- ""
- "
-{
- if (hppa_branch_type != CMP_SI)
- FAIL;
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
-}")
-
-(define_expand "sgtu"
- [(set (match_operand:SI 0 "register_operand" "")
- (gtu:SI (match_dup 1)
- (match_dup 2)))]
- ""
- "
-{
- if (hppa_branch_type != CMP_SI)
- FAIL;
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
-}")
-
-(define_expand "sleu"
- [(set (match_operand:SI 0 "register_operand" "")
- (leu:SI (match_dup 1)
- (match_dup 2)))]
- ""
- "
-{
- if (hppa_branch_type != CMP_SI)
- FAIL;
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
-}")
-
-(define_expand "sgeu"
- [(set (match_operand:SI 0 "register_operand" "")
- (geu:SI (match_dup 1)
- (match_dup 2)))]
- ""
- "
-{
- if (hppa_branch_type != CMP_SI)
- FAIL;
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
-}")
-
-;; Instruction canonicalization puts immediate operands second, which
-;; is the reverse of what we want.
-
-(define_insn "scc"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (match_operator:SI 3 "comparison_operator"
- [(match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "arith11_operand" "rI")]))]
- ""
- "com%I2clr,%B3 %2,%1,%0\;ldi 1,%0"
- [(set_attr "type" "binary")
- (set_attr "length" "8")])
-
-(define_insn "iorscc"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (ior:SI (match_operator:SI 3 "comparison_operator"
- [(match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "arith11_operand" "rI")])
- (match_operator:SI 6 "comparison_operator"
- [(match_operand:SI 4 "register_operand" "r")
- (match_operand:SI 5 "arith11_operand" "rI")])))]
- ""
- "com%I2clr,%S3 %2,%1,0\;com%I5clr,%B6 %5,%4,%0\;ldi 1,%0"
- [(set_attr "type" "binary")
- (set_attr "length" "12")])
-
-;; Combiner patterns for common operations performed with the output
-;; from an scc insn (negscc and incscc).
-(define_insn "negscc"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (neg:SI (match_operator:SI 3 "comparison_operator"
- [(match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "arith11_operand" "rI")])))]
- ""
- "com%I2clr,%B3 %2,%1,%0\;ldi -1,%0"
- [(set_attr "type" "binary")
- (set_attr "length" "8")])
-
-;; Patterns for adding/subtracting the result of a boolean expression from
-;; a register. First we have special patterns that make use of the carry
-;; bit, and output only two instructions. For the cases we can't in
-;; general do in two instructions, the incscc pattern at the end outputs
-;; two or three instructions.
-
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (plus:SI (leu:SI (match_operand:SI 2 "register_operand" "r")
- (match_operand:SI 3 "arith11_operand" "rI"))
- (match_operand:SI 1 "register_operand" "r")))]
- ""
- "sub%I3 %3,%2,0\;addc 0,%1,%0"
- [(set_attr "type" "binary")
- (set_attr "length" "8")])
-
-; This need only accept registers for op3, since canonicalization
-; replaces geu with gtu when op3 is an integer.
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (plus:SI (geu:SI (match_operand:SI 2 "register_operand" "r")
- (match_operand:SI 3 "register_operand" "r"))
- (match_operand:SI 1 "register_operand" "r")))]
- ""
- "sub %2,%3,0\;addc 0,%1,%0"
- [(set_attr "type" "binary")
- (set_attr "length" "8")])
-
-; Match only integers for op3 here. This is used as canonical form of the
-; geu pattern when op3 is an integer. Don't match registers since we can't
-; make better code than the general incscc pattern.
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (plus:SI (gtu:SI (match_operand:SI 2 "register_operand" "r")
- (match_operand:SI 3 "int11_operand" "I"))
- (match_operand:SI 1 "register_operand" "r")))]
- ""
- "addi %k3,%2,0\;addc 0,%1,%0"
- [(set_attr "type" "binary")
- (set_attr "length" "8")])
-
-(define_insn "incscc"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (plus:SI (match_operator:SI 4 "comparison_operator"
- [(match_operand:SI 2 "register_operand" "r,r")
- (match_operand:SI 3 "arith11_operand" "rI,rI")])
- (match_operand:SI 1 "register_operand" "0,?r")))]
- ""
- "@
- com%I3clr,%B4 %3,%2,0\;addi 1,%0,%0
- com%I3clr,%B4 %3,%2,0\;addi,tr 1,%1,%0\;copy %1,%0"
- [(set_attr "type" "binary,binary")
- (set_attr "length" "8,12")])
-
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (minus:SI (match_operand:SI 1 "register_operand" "r")
- (gtu:SI (match_operand:SI 2 "register_operand" "r")
- (match_operand:SI 3 "arith11_operand" "rI"))))]
- ""
- "sub%I3 %3,%2,0\;subb %1,0,%0"
- [(set_attr "type" "binary")
- (set_attr "length" "8")])
-
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
- (gtu:SI (match_operand:SI 2 "register_operand" "r")
- (match_operand:SI 3 "arith11_operand" "rI")))
- (match_operand:SI 4 "register_operand" "r")))]
- ""
- "sub%I3 %3,%2,0\;subb %1,%4,%0"
- [(set_attr "type" "binary")
- (set_attr "length" "8")])
-
-; This need only accept registers for op3, since canonicalization
-; replaces ltu with leu when op3 is an integer.
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (minus:SI (match_operand:SI 1 "register_operand" "r")
- (ltu:SI (match_operand:SI 2 "register_operand" "r")
- (match_operand:SI 3 "register_operand" "r"))))]
- ""
- "sub %2,%3,0\;subb %1,0,%0"
- [(set_attr "type" "binary")
- (set_attr "length" "8")])
-
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
- (ltu:SI (match_operand:SI 2 "register_operand" "r")
- (match_operand:SI 3 "register_operand" "r")))
- (match_operand:SI 4 "register_operand" "r")))]
- ""
- "sub %2,%3,0\;subb %1,%4,%0"
- [(set_attr "type" "binary")
- (set_attr "length" "8")])
-
-; Match only integers for op3 here. This is used as canonical form of the
-; ltu pattern when op3 is an integer. Don't match registers since we can't
-; make better code than the general incscc pattern.
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (minus:SI (match_operand:SI 1 "register_operand" "r")
- (leu:SI (match_operand:SI 2 "register_operand" "r")
- (match_operand:SI 3 "int11_operand" "I"))))]
- ""
- "addi %k3,%2,0\;subb %1,0,%0"
- [(set_attr "type" "binary")
- (set_attr "length" "8")])
-
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (minus:SI (minus:SI (match_operand:SI 1 "register_operand" "r")
- (leu:SI (match_operand:SI 2 "register_operand" "r")
- (match_operand:SI 3 "int11_operand" "I")))
- (match_operand:SI 4 "register_operand" "r")))]
- ""
- "addi %k3,%2,0\;subb %1,%4,%0"
- [(set_attr "type" "binary")
- (set_attr "length" "8")])
-
-(define_insn "decscc"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (minus:SI (match_operand:SI 1 "register_operand" "0,?r")
- (match_operator:SI 4 "comparison_operator"
- [(match_operand:SI 2 "register_operand" "r,r")
- (match_operand:SI 3 "arith11_operand" "rI,rI")])))]
- ""
- "@
- com%I3clr,%B4 %3,%2,0\;addi -1,%0,%0
- com%I3clr,%B4 %3,%2,0\;addi,tr -1,%1,%0\;copy %1,%0"
- [(set_attr "type" "binary,binary")
- (set_attr "length" "8,12")])
-
-; Patterns for max and min. (There is no need for an earlyclobber in the
-; last alternative since the middle alternative will match if op0 == op1.)
-
-(define_insn "sminsi3"
- [(set (match_operand:SI 0 "register_operand" "=r,r,r")
- (smin:SI (match_operand:SI 1 "register_operand" "%0,0,r")
- (match_operand:SI 2 "arith11_operand" "r,I,M")))]
- ""
- "@
- comclr,> %2,%0,0\;copy %2,%0
- comiclr,> %2,%0,0\;ldi %2,%0
- comclr,> %1,%2,%0\;copy %1,%0"
-[(set_attr "type" "multi,multi,multi")
- (set_attr "length" "8,8,8")])
-
-(define_insn "uminsi3"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (umin:SI (match_operand:SI 1 "register_operand" "%0,0")
- (match_operand:SI 2 "arith11_operand" "r,I")))]
- ""
- "@
- comclr,>> %2,%0,0\;copy %2,%0
- comiclr,>> %2,%0,0\;ldi %2,%0"
-[(set_attr "type" "multi,multi")
- (set_attr "length" "8,8")])
-
-(define_insn "smaxsi3"
- [(set (match_operand:SI 0 "register_operand" "=r,r,r")
- (smax:SI (match_operand:SI 1 "register_operand" "%0,0,r")
- (match_operand:SI 2 "arith11_operand" "r,I,M")))]
- ""
- "@
- comclr,< %2,%0,0\;copy %2,%0
- comiclr,< %2,%0,0\;ldi %2,%0
- comclr,< %1,%2,%0\;copy %1,%0"
-[(set_attr "type" "multi,multi,multi")
- (set_attr "length" "8,8,8")])
-
-(define_insn "umaxsi3"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (umax:SI (match_operand:SI 1 "register_operand" "%0,0")
- (match_operand:SI 2 "arith11_operand" "r,I")))]
- ""
- "@
- comclr,<< %2,%0,0\;copy %2,%0
- comiclr,<< %2,%0,0\;ldi %2,%0"
-[(set_attr "type" "multi,multi")
- (set_attr "length" "8,8")])
-
-(define_insn "abssi2"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (abs:SI (match_operand:SI 1 "register_operand" "r")))]
- ""
- "or,>= %%r0,%1,%0\;subi 0,%0,%0"
- [(set_attr "type" "multi")
- (set_attr "length" "8")])
-
-;;; Experimental conditional move patterns
-
-(define_expand "movsicc"
- [(set (match_operand:SI 0 "register_operand" "")
- (if_then_else:SI
- (match_operator 1 "comparison_operator"
- [(match_dup 4)
- (match_dup 5)])
- (match_operand:SI 2 "reg_or_cint_move_operand" "")
- (match_operand:SI 3 "reg_or_cint_move_operand" "")))]
- ""
- "
-{
- enum rtx_code code = GET_CODE (operands[1]);
-
- if (hppa_branch_type != CMP_SI)
- FAIL;
-
- /* operands[1] is currently the result of compare_from_rtx. We want to
- emit a compare of the original operands. */
- operands[1] = gen_rtx_fmt_ee (code, SImode, hppa_compare_op0, hppa_compare_op1);
- operands[4] = hppa_compare_op0;
- operands[5] = hppa_compare_op1;
-}")
-
-; We need the first constraint alternative in order to avoid
-; earlyclobbers on all other alternatives.
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r")
- (if_then_else:SI
- (match_operator 5 "comparison_operator"
- [(match_operand:SI 3 "register_operand" "r,r,r,r,r")
- (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI,rI")])
- (match_operand:SI 1 "reg_or_cint_move_operand" "0,r,J,N,K")
- (const_int 0)))]
- ""
- "@
- com%I4clr,%S5 %4,%3,0\;ldi 0,%0
- com%I4clr,%B5 %4,%3,%0\;copy %1,%0
- com%I4clr,%B5 %4,%3,%0\;ldi %1,%0
- com%I4clr,%B5 %4,%3,%0\;ldil L'%1,%0
- com%I4clr,%B5 %4,%3,%0\;zdepi %Z1,%0"
- [(set_attr "type" "multi,multi,multi,multi,nullshift")
- (set_attr "length" "8,8,8,8,8")])
-
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,r,r,r")
- (if_then_else:SI
- (match_operator 5 "comparison_operator"
- [(match_operand:SI 3 "register_operand" "r,r,r,r,r,r,r,r")
- (match_operand:SI 4 "arith11_operand" "rI,rI,rI,rI,rI,rI,rI,rI")])
- (match_operand:SI 1 "reg_or_cint_move_operand" "0,0,0,0,r,J,N,K")
- (match_operand:SI 2 "reg_or_cint_move_operand" "r,J,N,K,0,0,0,0")))]
- ""
- "@
- com%I4clr,%S5 %4,%3,0\;copy %2,%0
- com%I4clr,%S5 %4,%3,0\;ldi %2,%0
- com%I4clr,%S5 %4,%3,0\;ldil L'%2,%0
- com%I4clr,%S5 %4,%3,0\;zdepi %Z2,%0
- com%I4clr,%B5 %4,%3,0\;copy %1,%0
- com%I4clr,%B5 %4,%3,0\;ldi %1,%0
- com%I4clr,%B5 %4,%3,0\;ldil L'%1,%0
- com%I4clr,%B5 %4,%3,0\;zdepi %Z1,%0"
- [(set_attr "type" "multi,multi,multi,nullshift,multi,multi,multi,nullshift")
- (set_attr "length" "8,8,8,8,8,8,8,8")])
-
-;; Conditional Branches
-
-(define_expand "beq"
- [(set (pc)
- (if_then_else (eq (match_dup 1) (match_dup 2))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (hppa_branch_type != CMP_SI)
- {
- emit_insn (gen_cmp_fp (EQ, hppa_compare_op0, hppa_compare_op1));
- emit_bcond_fp (NE, operands[0]);
- DONE;
- }
- /* set up operands from compare. */
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
- /* fall through and generate default code */
-}")
-
-(define_expand "bne"
- [(set (pc)
- (if_then_else (ne (match_dup 1) (match_dup 2))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (hppa_branch_type != CMP_SI)
- {
- emit_insn (gen_cmp_fp (NE, hppa_compare_op0, hppa_compare_op1));
- emit_bcond_fp (NE, operands[0]);
- DONE;
- }
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
-}")
-
-(define_expand "bgt"
- [(set (pc)
- (if_then_else (gt (match_dup 1) (match_dup 2))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (hppa_branch_type != CMP_SI)
- {
- emit_insn (gen_cmp_fp (GT, hppa_compare_op0, hppa_compare_op1));
- emit_bcond_fp (NE, operands[0]);
- DONE;
- }
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
-}")
-
-(define_expand "blt"
- [(set (pc)
- (if_then_else (lt (match_dup 1) (match_dup 2))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (hppa_branch_type != CMP_SI)
- {
- emit_insn (gen_cmp_fp (LT, hppa_compare_op0, hppa_compare_op1));
- emit_bcond_fp (NE, operands[0]);
- DONE;
- }
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
-}")
-
-(define_expand "bge"
- [(set (pc)
- (if_then_else (ge (match_dup 1) (match_dup 2))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (hppa_branch_type != CMP_SI)
- {
- emit_insn (gen_cmp_fp (GE, hppa_compare_op0, hppa_compare_op1));
- emit_bcond_fp (NE, operands[0]);
- DONE;
- }
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
-}")
-
-(define_expand "ble"
- [(set (pc)
- (if_then_else (le (match_dup 1) (match_dup 2))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (hppa_branch_type != CMP_SI)
- {
- emit_insn (gen_cmp_fp (LE, hppa_compare_op0, hppa_compare_op1));
- emit_bcond_fp (NE, operands[0]);
- DONE;
- }
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
-}")
-
-(define_expand "bgtu"
- [(set (pc)
- (if_then_else (gtu (match_dup 1) (match_dup 2))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (hppa_branch_type != CMP_SI)
- FAIL;
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
-}")
-
-(define_expand "bltu"
- [(set (pc)
- (if_then_else (ltu (match_dup 1) (match_dup 2))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (hppa_branch_type != CMP_SI)
- FAIL;
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
-}")
-
-(define_expand "bgeu"
- [(set (pc)
- (if_then_else (geu (match_dup 1) (match_dup 2))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (hppa_branch_type != CMP_SI)
- FAIL;
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
-}")
-
-(define_expand "bleu"
- [(set (pc)
- (if_then_else (leu (match_dup 1) (match_dup 2))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "
-{
- if (hppa_branch_type != CMP_SI)
- FAIL;
- operands[1] = hppa_compare_op0;
- operands[2] = hppa_compare_op1;
-}")
-
-;; Match the branch patterns.
-
-
-;; Note a long backward conditional branch with an annulled delay slot
-;; has a length of 12.
-(define_insn ""
- [(set (pc)
- (if_then_else
- (match_operator 3 "comparison_operator"
- [(match_operand:SI 1 "reg_or_0_operand" "rM")
- (match_operand:SI 2 "arith5_operand" "rL")])
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "*
-{
- return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
- get_attr_length (insn), 0, insn);
-}"
-[(set_attr "type" "cbranch")
- (set (attr "length")
- (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
- (const_int 262100))
- (const_int 8)
- (eq (symbol_ref "flag_pic") (const_int 0))
- (const_int 20)]
- (const_int 28)))])
-
-;; Match the negated branch.
-
-(define_insn ""
- [(set (pc)
- (if_then_else
- (match_operator 3 "comparison_operator"
- [(match_operand:SI 1 "reg_or_0_operand" "rM")
- (match_operand:SI 2 "arith5_operand" "rL")])
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "*
-{
- return output_cbranch (operands, INSN_ANNULLED_BRANCH_P (insn),
- get_attr_length (insn), 1, insn);
-}"
-[(set_attr "type" "cbranch")
- (set (attr "length")
- (cond [(lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (lt (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
- (const_int 262100))
- (const_int 8)
- (eq (symbol_ref "flag_pic") (const_int 0))
- (const_int 20)]
- (const_int 28)))])
-
-;; Branch on Bit patterns.
-(define_insn ""
- [(set (pc)
- (if_then_else
- (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
- (const_int 1)
- (match_operand:SI 1 "uint5_operand" ""))
- (const_int 0))
- (label_ref (match_operand 2 "" ""))
- (pc)))]
- ""
- "*
-{
- return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
- get_attr_length (insn), 0, insn, 0);
-}"
-[(set_attr "type" "cbranch")
- (set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8)))])
-
-(define_insn ""
- [(set (pc)
- (if_then_else
- (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
- (const_int 1)
- (match_operand:SI 1 "uint5_operand" ""))
- (const_int 0))
- (pc)
- (label_ref (match_operand 2 "" ""))))]
- ""
- "*
-{
- return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
- get_attr_length (insn), 1, insn, 0);
-}"
-[(set_attr "type" "cbranch")
- (set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8)))])
-
-(define_insn ""
- [(set (pc)
- (if_then_else
- (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
- (const_int 1)
- (match_operand:SI 1 "uint5_operand" ""))
- (const_int 0))
- (label_ref (match_operand 2 "" ""))
- (pc)))]
- ""
- "*
-{
- return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
- get_attr_length (insn), 0, insn, 1);
-}"
-[(set_attr "type" "cbranch")
- (set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8)))])
-
-(define_insn ""
- [(set (pc)
- (if_then_else
- (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
- (const_int 1)
- (match_operand:SI 1 "uint5_operand" ""))
- (const_int 0))
- (pc)
- (label_ref (match_operand 2 "" ""))))]
- ""
- "*
-{
- return output_bb (operands, INSN_ANNULLED_BRANCH_P (insn),
- get_attr_length (insn), 1, insn, 1);
-}"
-[(set_attr "type" "cbranch")
- (set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8)))])
-
-;; Branch on Variable Bit patterns.
-(define_insn ""
- [(set (pc)
- (if_then_else
- (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
- (const_int 1)
- (match_operand:SI 1 "register_operand" "q"))
- (const_int 0))
- (label_ref (match_operand 2 "" ""))
- (pc)))]
- ""
- "*
-{
- return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
- get_attr_length (insn), 0, insn, 0);
-}"
-[(set_attr "type" "cbranch")
- (set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8)))])
-
-(define_insn ""
- [(set (pc)
- (if_then_else
- (ne (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
- (const_int 1)
- (match_operand:SI 1 "register_operand" "q"))
- (const_int 0))
- (pc)
- (label_ref (match_operand 2 "" ""))))]
- ""
- "*
-{
- return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
- get_attr_length (insn), 1, insn, 0);
-}"
-[(set_attr "type" "cbranch")
- (set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8)))])
-
-(define_insn ""
- [(set (pc)
- (if_then_else
- (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
- (const_int 1)
- (match_operand:SI 1 "register_operand" "q"))
- (const_int 0))
- (label_ref (match_operand 2 "" ""))
- (pc)))]
- ""
- "*
-{
- return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
- get_attr_length (insn), 0, insn, 1);
-}"
-[(set_attr "type" "cbranch")
- (set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8)))])
-
-(define_insn ""
- [(set (pc)
- (if_then_else
- (eq (zero_extract:SI (match_operand:SI 0 "register_operand" "r")
- (const_int 1)
- (match_operand:SI 1 "register_operand" "q"))
- (const_int 0))
- (pc)
- (label_ref (match_operand 2 "" ""))))]
- ""
- "*
-{
- return output_bvb (operands, INSN_ANNULLED_BRANCH_P (insn),
- get_attr_length (insn), 1, insn, 1);
-}"
-[(set_attr "type" "cbranch")
- (set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8)))])
-
-;; Floating point branches
-(define_insn ""
- [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- "! TARGET_SOFT_FLOAT"
- "*
-{
- if (INSN_ANNULLED_BRANCH_P (insn))
- return \"ftest\;bl,n %0,0\";
- else
- return \"ftest\;bl%* %0,0\";
-}"
- [(set_attr "type" "fbranch")
- (set_attr "length" "8")])
-
-(define_insn ""
- [(set (pc) (if_then_else (ne (reg:CCFP 0) (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- "! TARGET_SOFT_FLOAT"
- "*
-{
- if (INSN_ANNULLED_BRANCH_P (insn))
- return \"ftest\;add,tr 0,0,0\;bl,n %0,0\";
- else
- return \"ftest\;add,tr 0,0,0\;bl%* %0,0\";
-}"
- [(set_attr "type" "fbranch")
- (set_attr "length" "12")])
-
-;; Move instructions
-
-(define_expand "movsi"
- [(set (match_operand:SI 0 "general_operand" "")
- (match_operand:SI 1 "general_operand" ""))]
- ""
- "
-{
- if (emit_move_sequence (operands, SImode, 0))
- DONE;
-}")
-
-;; Reloading an SImode or DImode value requires a scratch register if
-;; going in to or out of float point registers.
-
-(define_expand "reload_insi"
- [(set (match_operand:SI 0 "register_operand" "=Z")
- (match_operand:SI 1 "non_hard_reg_operand" ""))
- (clobber (match_operand:SI 2 "register_operand" "=&r"))]
- ""
- "
-{
- if (emit_move_sequence (operands, SImode, operands[2]))
- DONE;
-
- /* We don't want the clobber emitted, so handle this ourselves. */
- emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
- DONE;
-}")
-
-(define_expand "reload_outsi"
- [(set (match_operand:SI 0 "non_hard_reg_operand" "")
- (match_operand:SI 1 "register_operand" "Z"))
- (clobber (match_operand:SI 2 "register_operand" "=&r"))]
- ""
- "
-{
- if (emit_move_sequence (operands, SImode, operands[2]))
- DONE;
-
- /* We don't want the clobber emitted, so handle this ourselves. */
- emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
- DONE;
-}")
-
-;;; pic symbol references
-
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "symbolic_operand" ""))))]
- "flag_pic && operands[1] == pic_offset_table_rtx"
- "ldw T'%2(%1),%0"
- [(set_attr "type" "load")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand"
- "=r,r,r,r,r,Q,*q,!f,f,*TR")
- (match_operand:SI 1 "move_operand"
- "r,J,N,K,RQ,rM,rM,!fM,*RT,f"))]
- "(register_operand (operands[0], SImode)
- || reg_or_0_operand (operands[1], SImode))
- && ! TARGET_SOFT_FLOAT"
- "@
- copy %1,%0
- ldi %1,%0
- ldil L'%1,%0
- zdepi %Z1,%0
- ldw%M1 %1,%0
- stw%M0 %r1,%0
- mtsar %r1
- fcpy,sgl %r1,%0
- fldw%F1 %1,%0
- fstw%F0 %1,%0"
- [(set_attr "type" "move,move,move,shift,load,store,move,fpalu,fpload,fpstore")
- (set_attr "pa_combine_type" "addmove")
- (set_attr "length" "4,4,4,4,4,4,4,4,4,4")])
-
-(define_insn ""
- [(set (match_operand:SI 0 "reg_or_nonsymb_mem_operand"
- "=r,r,r,r,r,Q,*q")
- (match_operand:SI 1 "move_operand"
- "r,J,N,K,RQ,rM,rM"))]
- "(register_operand (operands[0], SImode)
- || reg_or_0_operand (operands[1], SImode))
- && TARGET_SOFT_FLOAT"
- "@
- copy %1,%0
- ldi %1,%0
- ldil L'%1,%0
- zdepi %Z1,%0
- ldw%M1 %1,%0
- stw%M0 %r1,%0
- mtsar %r1"
- [(set_attr "type" "move,move,move,move,load,store,move")
- (set_attr "pa_combine_type" "addmove")
- (set_attr "length" "4,4,4,4,4,4,4")])
-
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (mem:SI (plus:SI (match_operand:SI 1 "basereg_operand" "r")
- (match_operand:SI 2 "register_operand" "r"))))]
- "! TARGET_DISABLE_INDEXING"
- "*
-{
- /* Reload can create backwards (relative to cse) unscaled index
- address modes when eliminating registers and possibly for
- pseudos that don't get hard registers. Deal with it. */
- if (operands[2] == hard_frame_pointer_rtx
- || operands[2] == stack_pointer_rtx)
- return \"ldwx %1(0,%2),%0\";
- else
- return \"ldwx %2(0,%1),%0\";
-}"
- [(set_attr "type" "load")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "basereg_operand" "r"))))]
- "! TARGET_DISABLE_INDEXING"
- "*
-{
- /* Reload can create backwards (relative to cse) unscaled index
- address modes when eliminating registers and possibly for
- pseudos that don't get hard registers. Deal with it. */
- if (operands[1] == hard_frame_pointer_rtx
- || operands[1] == stack_pointer_rtx)
- return \"ldwx %2(0,%1),%0\";
- else
- return \"ldwx %1(0,%2),%0\";
-}"
- [(set_attr "type" "load")
- (set_attr "length" "4")])
-
-;; Load or store with base-register modification.
-
-(define_insn "pre_ldwm"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (mem:SI (plus:SI (match_operand:SI 1 "register_operand" "+r")
- (match_operand:SI 2 "pre_cint_operand" ""))))
- (set (match_dup 1)
- (plus:SI (match_dup 1) (match_dup 2)))]
- ""
- "*
-{
- if (INTVAL (operands[2]) < 0)
- return \"ldwm %2(0,%1),%0\";
- return \"ldws,mb %2(0,%1),%0\";
-}"
- [(set_attr "type" "load")
- (set_attr "length" "4")])
-
-(define_insn "pre_stwm"
- [(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "+r")
- (match_operand:SI 1 "pre_cint_operand" "")))
- (match_operand:SI 2 "reg_or_0_operand" "rM"))
- (set (match_dup 0)
- (plus:SI (match_dup 0) (match_dup 1)))]
- ""
- "*
-{
- if (INTVAL (operands[1]) < 0)
- return \"stwm %r2,%1(0,%0)\";
- return \"stws,mb %r2,%1(0,%0)\";
-}"
- [(set_attr "type" "store")
- (set_attr "length" "4")])
-
-(define_insn "post_ldwm"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (mem:SI (match_operand:SI 1 "register_operand" "+r")))
- (set (match_dup 1)
- (plus:SI (match_dup 1)
- (match_operand:SI 2 "post_cint_operand" "")))]
- ""
- "*
-{
- if (INTVAL (operands[2]) > 0)
- return \"ldwm %2(0,%1),%0\";
- return \"ldws,ma %2(0,%1),%0\";
-}"
- [(set_attr "type" "load")
- (set_attr "length" "4")])
-
-(define_insn "post_stwm"
- [(set (mem:SI (match_operand:SI 0 "register_operand" "+r"))
- (match_operand:SI 1 "reg_or_0_operand" "rM"))
- (set (match_dup 0)
- (plus:SI (match_dup 0)
- (match_operand:SI 2 "post_cint_operand" "")))]
- ""
- "*
-{
- if (INTVAL (operands[2]) > 0)
- return \"stwm %r1,%2(0,%0)\";
- return \"stws,ma %r1,%2(0,%0)\";
-}"
- [(set_attr "type" "store")
- (set_attr "length" "4")])
-
-;; For pic
-;; Note since this pattern can be created at reload time (via movsi), all
-;; the same rules for movsi apply here. (no new pseudos, no temporaries).
-(define_insn "pic_load_label"
- [(set (match_operand:SI 0 "register_operand" "=a")
- (match_operand:SI 1 "pic_label_operand" ""))]
- ""
- "*
-{
- rtx label_rtx = gen_label_rtx ();
- rtx xoperands[3];
- extern FILE *asm_out_file;
-
- xoperands[0] = operands[0];
- xoperands[1] = operands[1];
- xoperands[2] = label_rtx;
- output_asm_insn (\"bl .+8,%0\", xoperands);
- output_asm_insn (\"depi 0,31,2,%0\", xoperands);
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
- CODE_LABEL_NUMBER (label_rtx));
-
- /* If we're trying to load the address of a label that happens to be
- close, then we can use a shorter sequence. */
- if (GET_CODE (operands[1]) == LABEL_REF
- && insn_addresses
- && abs (insn_addresses[INSN_UID (XEXP (operands[1], 0))]
- - insn_addresses[INSN_UID (insn)]) < 8100)
- {
- /* Prefixing with R% here is wrong, it extracts just 11 bits and is
- always non-negative. */
- output_asm_insn (\"ldo %1-%2(%0),%0\", xoperands);
- }
- else
- {
- output_asm_insn (\"addil L%%%1-%2,%0\", xoperands);
- output_asm_insn (\"ldo R%%%1-%2(%0),%0\", xoperands);
- }
- return \"\";
-}"
- [(set_attr "type" "multi")
- (set_attr "length" "16")]) ; 12 or 16
-
-(define_insn "pic2_highpart"
- [(set (match_operand:SI 0 "register_operand" "=a")
- (plus:SI (match_operand:SI 1 "register_operand" "r")
- (high:SI (match_operand 2 "" ""))))]
- "symbolic_operand (operands[2], Pmode)
- && ! function_label_operand (operands[2])
- && flag_pic == 2"
- "addil LT'%G2,%1"
- [(set_attr "type" "binary")
- (set_attr "length" "4")])
-
-; We need this to make sure CSE doesn't simplify a memory load with a
-; symbolic address, whose content it think it knows. For PIC, what CSE
-; think is the real value will be the address of that value.
-(define_insn "pic2_lo_sum"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (mem:SI (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
- (unspec:SI [(match_operand:SI 2 "symbolic_operand" "")] 0))))]
- ""
- "*
-{
- if (flag_pic != 2)
- abort ();
- return \"ldw RT'%G2(%1),%0\";
-}"
- [(set_attr "type" "load")
- (set_attr "length" "4")])
-
-
-;; Always use addil rather than ldil;add sequences. This allows the
-;; HP linker to eliminate the dp relocation if the symbolic operand
-;; lives in the TEXT space.
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=a")
- (high:SI (match_operand 1 "" "")))]
- "symbolic_operand (operands[1], Pmode)
- && ! function_label_operand (operands[1])
- && ! read_only_operand (operands[1])
- && ! flag_pic"
- "*
-{
- if (TARGET_LONG_LOAD_STORE)
- return \"addil NLR'%H1,%%r27\;ldo N'%H1(%%r1),%%r1\";
- else
- return \"addil LR'%H1,%%r27\";
-}"
- [(set_attr "type" "binary")
- (set (attr "length")
- (if_then_else (eq (symbol_ref "TARGET_LONG_LOAD_STORE") (const_int 0))
- (const_int 4)
- (const_int 8)))])
-
-
-;; This is for use in the prologue/epilogue code. We need it
-;; to add large constants to a stack pointer or frame pointer.
-;; Because of the additional %r1 pressure, we probably do not
-;; want to use this in general code, so make it available
-;; only after reload.
-(define_insn "add_high_const"
- [(set (match_operand:SI 0 "register_operand" "=!a,*r")
- (plus:SI (match_operand:SI 1 "register_operand" "r,r")
- (high:SI (match_operand 2 "const_int_operand" ""))))]
- "reload_completed"
- "@
- addil L'%G2,%1
- ldil L'%G2,%0\;addl %0,%1,%0"
- [(set_attr "type" "binary,binary")
- (set_attr "length" "4,8")])
-
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (high:SI (match_operand 1 "" "")))]
- "(!flag_pic || !symbolic_operand (operands[1]), Pmode)
- && !is_function_label_plus_const (operands[1])"
- "*
-{
- if (symbolic_operand (operands[1], Pmode))
- return \"ldil LR'%H1,%0\";
- else
- return \"ldil L'%G1,%0\";
-}"
- [(set_attr "type" "move")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (lo_sum:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "immediate_operand" "i")))]
- "!is_function_label_plus_const (operands[2])"
- "*
-{
- if (flag_pic && symbolic_operand (operands[2], Pmode))
- abort ();
- else if (symbolic_operand (operands[2], Pmode))
- return \"ldo RR'%G2(%1),%0\";
- else
- return \"ldo R'%G2(%1),%0\";
-}"
- [(set_attr "type" "move")
- (set_attr "length" "4")])
-
-;; Now that a symbolic_address plus a constant is broken up early
-;; in the compilation phase (for better CSE) we need a special
-;; combiner pattern to load the symbolic address plus the constant
-;; in only 2 instructions. (For cases where the symbolic address
-;; was not a common subexpression.)
-(define_split
- [(set (match_operand:SI 0 "register_operand" "")
- (match_operand:SI 1 "symbolic_operand" ""))
- (clobber (match_operand:SI 2 "register_operand" ""))]
- "! (flag_pic && pic_label_operand (operands[1], SImode))"
- [(set (match_dup 2) (high:SI (match_dup 1)))
- (set (match_dup 0) (lo_sum:SI (match_dup 2) (match_dup 1)))]
- "")
-
-;; hppa_legitimize_address goes to a great deal of trouble to
-;; create addresses which use indexing. In some cases, this
-;; is a lose because there isn't any store instructions which
-;; allow indexed addresses (with integer register source).
-;;
-;; These define_splits try to turn a 3 insn store into
-;; a 2 insn store with some creative RTL rewriting.
-(define_split
- [(set (mem:SI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
- (match_operand:SI 1 "shadd_operand" ""))
- (plus:SI (match_operand:SI 2 "register_operand" "")
- (match_operand:SI 3 "const_int_operand" ""))))
- (match_operand:SI 4 "register_operand" ""))
- (clobber (match_operand:SI 5 "register_operand" ""))]
- ""
- [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
- (match_dup 2)))
- (set (mem:SI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
- "")
-
-(define_split
- [(set (mem:HI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
- (match_operand:SI 1 "shadd_operand" ""))
- (plus:SI (match_operand:SI 2 "register_operand" "")
- (match_operand:SI 3 "const_int_operand" ""))))
- (match_operand:HI 4 "register_operand" ""))
- (clobber (match_operand:SI 5 "register_operand" ""))]
- ""
- [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
- (match_dup 2)))
- (set (mem:HI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
- "")
-
-(define_split
- [(set (mem:QI (plus:SI (mult:SI (match_operand:SI 0 "register_operand" "")
- (match_operand:SI 1 "shadd_operand" ""))
- (plus:SI (match_operand:SI 2 "register_operand" "")
- (match_operand:SI 3 "const_int_operand" ""))))
- (match_operand:QI 4 "register_operand" ""))
- (clobber (match_operand:SI 5 "register_operand" ""))]
- ""
- [(set (match_dup 5) (plus:SI (mult:SI (match_dup 0) (match_dup 1))
- (match_dup 2)))
- (set (mem:QI (plus:SI (match_dup 5) (match_dup 3))) (match_dup 4))]
- "")
-
-(define_expand "movhi"
- [(set (match_operand:HI 0 "general_operand" "")
- (match_operand:HI 1 "general_operand" ""))]
- ""
- "
-{
- if (emit_move_sequence (operands, HImode, 0))
- DONE;
-}")
-
-(define_insn ""
- [(set (match_operand:HI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q,*q,!f")
- (match_operand:HI 1 "move_operand" "r,J,N,K,RQ,rM,rM,!fM"))]
- "register_operand (operands[0], HImode)
- || reg_or_0_operand (operands[1], HImode)"
- "@
- copy %1,%0
- ldi %1,%0
- ldil L'%1,%0
- zdepi %Z1,%0
- ldh%M1 %1,%0
- sth%M0 %r1,%0
- mtsar %r1
- fcpy,sgl %r1,%0"
- [(set_attr "type" "move,move,move,shift,load,store,move,fpalu")
- (set_attr "pa_combine_type" "addmove")
- (set_attr "length" "4,4,4,4,4,4,4,4")])
-
-(define_insn ""
- [(set (match_operand:HI 0 "register_operand" "=r")
- (mem:HI (plus:SI (match_operand:SI 1 "basereg_operand" "r")
- (match_operand:SI 2 "register_operand" "r"))))]
- "! TARGET_DISABLE_INDEXING"
- "*
-{
- /* Reload can create backwards (relative to cse) unscaled index
- address modes when eliminating registers and possibly for
- pseudos that don't get hard registers. Deal with it. */
- if (operands[2] == hard_frame_pointer_rtx
- || operands[2] == stack_pointer_rtx)
- return \"ldhx %1(0,%2),%0\";
- else
- return \"ldhx %2(0,%1),%0\";
-}"
- [(set_attr "type" "load")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:HI 0 "register_operand" "=r")
- (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "basereg_operand" "r"))))]
- "! TARGET_DISABLE_INDEXING"
- "*
-{
- /* Reload can create backwards (relative to cse) unscaled index
- address modes when eliminating registers and possibly for
- pseudos that don't get hard registers. Deal with it. */
- if (operands[1] == hard_frame_pointer_rtx
- || operands[1] == stack_pointer_rtx)
- return \"ldhx %2(0,%1),%0\";
- else
- return \"ldhx %1(0,%2),%0\";
-}"
- [(set_attr "type" "load")
- (set_attr "length" "4")])
-
-; Now zero extended variants.
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (zero_extend:SI (mem:HI
- (plus:SI
- (match_operand:SI 1 "basereg_operand" "r")
- (match_operand:SI 2 "register_operand" "r")))))]
- "! TARGET_DISABLE_INDEXING"
- "*
-{
- /* Reload can create backwards (relative to cse) unscaled index
- address modes when eliminating registers and possibly for
- pseudos that don't get hard registers. Deal with it. */
- if (operands[2] == hard_frame_pointer_rtx
- || operands[2] == stack_pointer_rtx)
- return \"ldhx %1(0,%2),%0\";
- else
- return \"ldhx %2(0,%1),%0\";
-}"
- [(set_attr "type" "load")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (zero_extend:SI (mem:HI
- (plus:SI
- (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "basereg_operand" "r")))))]
- "! TARGET_DISABLE_INDEXING"
- "*
-{
- /* Reload can create backwards (relative to cse) unscaled index
- address modes when eliminating registers and possibly for
- pseudos that don't get hard registers. Deal with it. */
- if (operands[1] == hard_frame_pointer_rtx
- || operands[1] == stack_pointer_rtx)
- return \"ldhx %2(0,%1),%0\";
- else
- return \"ldhx %1(0,%2),%0\";
-}"
- [(set_attr "type" "load")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:HI 0 "register_operand" "=r")
- (mem:HI (plus:SI (match_operand:SI 1 "register_operand" "+r")
- (match_operand:SI 2 "int5_operand" "L"))))
- (set (match_dup 1)
- (plus:SI (match_dup 1) (match_dup 2)))]
- ""
- "ldhs,mb %2(0,%1),%0"
- [(set_attr "type" "load")
- (set_attr "length" "4")])
-
-; And a zero extended variant.
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (zero_extend:SI (mem:HI
- (plus:SI
- (match_operand:SI 1 "register_operand" "+r")
- (match_operand:SI 2 "int5_operand" "L")))))
- (set (match_dup 1)
- (plus:SI (match_dup 1) (match_dup 2)))]
- ""
- "ldhs,mb %2(0,%1),%0"
- [(set_attr "type" "load")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (mem:HI (plus:SI (match_operand:SI 0 "register_operand" "+r")
- (match_operand:SI 1 "int5_operand" "L")))
- (match_operand:HI 2 "reg_or_0_operand" "rM"))
- (set (match_dup 0)
- (plus:SI (match_dup 0) (match_dup 1)))]
- ""
- "sths,mb %r2,%1(0,%0)"
- [(set_attr "type" "store")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:HI 0 "register_operand" "=r")
- (high:HI (match_operand 1 "const_int_operand" "")))]
- ""
- "ldil L'%G1,%0"
- [(set_attr "type" "move")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:HI 0 "register_operand" "=r")
- (lo_sum:HI (match_operand:HI 1 "register_operand" "r")
- (match_operand 2 "const_int_operand" "")))]
- ""
- "ldo R'%G2(%1),%0"
- [(set_attr "type" "move")
- (set_attr "length" "4")])
-
-(define_expand "movqi"
- [(set (match_operand:QI 0 "general_operand" "")
- (match_operand:QI 1 "general_operand" ""))]
- ""
- "
-{
- if (emit_move_sequence (operands, QImode, 0))
- DONE;
-}")
-
-(define_insn ""
- [(set (match_operand:QI 0 "reg_or_nonsymb_mem_operand" "=r,r,r,r,r,Q,*q,!f")
- (match_operand:QI 1 "move_operand" "r,J,N,K,RQ,rM,rM,!fM"))]
- "register_operand (operands[0], QImode)
- || reg_or_0_operand (operands[1], QImode)"
- "@
- copy %1,%0
- ldi %1,%0
- ldil L'%1,%0
- zdepi %Z1,%0
- ldb%M1 %1,%0
- stb%M0 %r1,%0
- mtsar %r1
- fcpy,sgl %r1,%0"
- [(set_attr "type" "move,move,move,shift,load,store,move,fpalu")
- (set_attr "pa_combine_type" "addmove")
- (set_attr "length" "4,4,4,4,4,4,4,4")])
-
-(define_insn ""
- [(set (match_operand:QI 0 "register_operand" "=r")
- (mem:QI (plus:SI (match_operand:SI 1 "basereg_operand" "r")
- (match_operand:SI 2 "register_operand" "r"))))]
- "! TARGET_DISABLE_INDEXING"
- "*
-{
- /* Reload can create backwards (relative to cse) unscaled index
- address modes when eliminating registers and possibly for
- pseudos that don't get hard registers. Deal with it. */
- if (operands[2] == hard_frame_pointer_rtx
- || operands[2] == stack_pointer_rtx)
- return \"ldbx %1(0,%2),%0\";
- else
- return \"ldbx %2(0,%1),%0\";
-}"
- [(set_attr "type" "load")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:QI 0 "register_operand" "=r")
- (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "basereg_operand" "r"))))]
- "! TARGET_DISABLE_INDEXING"
- "*
-{
- /* Reload can create backwards (relative to cse) unscaled index
- address modes when eliminating registers and possibly for
- pseudos that don't get hard registers. Deal with it. */
- if (operands[1] == hard_frame_pointer_rtx
- || operands[1] == stack_pointer_rtx)
- return \"ldbx %2(0,%1),%0\";
- else
- return \"ldbx %1(0,%2),%0\";
-}"
- [(set_attr "type" "load")
- (set_attr "length" "4")])
-
-; Indexed byte load with zero extension to SImode or HImode.
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (zero_extend:SI (mem:QI
- (plus:SI
- (match_operand:SI 1 "basereg_operand" "r")
- (match_operand:SI 2 "register_operand" "r")))))]
- "! TARGET_DISABLE_INDEXING"
- "*
-{
- /* Reload can create backwards (relative to cse) unscaled index
- address modes when eliminating registers and possibly for
- pseudos that don't get hard registers. Deal with it. */
- if (operands[2] == hard_frame_pointer_rtx
- || operands[2] == stack_pointer_rtx)
- return \"ldbx %1(0,%2),%0\";
- else
- return \"ldbx %2(0,%1),%0\";
-}"
- [(set_attr "type" "load")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (zero_extend:SI (mem:QI
- (plus:SI
- (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "basereg_operand" "r")))))]
- "! TARGET_DISABLE_INDEXING"
- "*
-{
- /* Reload can create backwards (relative to cse) unscaled index
- address modes when eliminating registers and possibly for
- pseudos that don't get hard registers. Deal with it. */
- if (operands[1] == hard_frame_pointer_rtx
- || operands[1] == stack_pointer_rtx)
- return \"ldbx %2(0,%1),%0\";
- else
- return \"ldbx %1(0,%2),%0\";
-}"
- [(set_attr "type" "load")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:HI 0 "register_operand" "=r")
- (zero_extend:HI (mem:QI
- (plus:SI
- (match_operand:SI 1 "basereg_operand" "r")
- (match_operand:SI 2 "register_operand" "r")))))]
- "! TARGET_DISABLE_INDEXING"
- "*
-{
- /* Reload can create backwards (relative to cse) unscaled index
- address modes when eliminating registers and possibly for
- pseudos that don't get hard registers. Deal with it. */
- if (operands[2] == hard_frame_pointer_rtx
- || operands[2] == stack_pointer_rtx)
- return \"ldbx %1(0,%2),%0\";
- else
- return \"ldbx %2(0,%1),%0\";
-}"
- [(set_attr "type" "load")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:HI 0 "register_operand" "=r")
- (zero_extend:HI (mem:QI
- (plus:SI
- (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "basereg_operand" "r")))))]
- "! TARGET_DISABLE_INDEXING"
- "*
-{
- /* Reload can create backwards (relative to cse) unscaled index
- address modes when eliminating registers and possibly for
- pseudos that don't get hard registers. Deal with it. */
- if (operands[1] == hard_frame_pointer_rtx
- || operands[1] == stack_pointer_rtx)
- return \"ldbx %2(0,%1),%0\";
- else
- return \"ldbx %1(0,%2),%0\";
-}"
- [(set_attr "type" "load")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:QI 0 "register_operand" "=r")
- (mem:QI (plus:SI (match_operand:SI 1 "register_operand" "+r")
- (match_operand:SI 2 "int5_operand" "L"))))
- (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
- ""
- "ldbs,mb %2(0,%1),%0"
- [(set_attr "type" "load")
- (set_attr "length" "4")])
-
-; Now the same thing with zero extensions.
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (zero_extend:SI (mem:QI (plus:SI
- (match_operand:SI 1 "register_operand" "+r")
- (match_operand:SI 2 "int5_operand" "L")))))
- (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
- ""
- "ldbs,mb %2(0,%1),%0"
- [(set_attr "type" "load")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:HI 0 "register_operand" "=r")
- (zero_extend:HI (mem:QI (plus:SI
- (match_operand:SI 1 "register_operand" "+r")
- (match_operand:SI 2 "int5_operand" "L")))))
- (set (match_dup 1) (plus:SI (match_dup 1) (match_dup 2)))]
- ""
- "ldbs,mb %2(0,%1),%0"
- [(set_attr "type" "load")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (mem:QI (plus:SI (match_operand:SI 0 "register_operand" "+r")
- (match_operand:SI 1 "int5_operand" "L")))
- (match_operand:QI 2 "reg_or_0_operand" "rM"))
- (set (match_dup 0)
- (plus:SI (match_dup 0) (match_dup 1)))]
- ""
- "stbs,mb %r2,%1(0,%0)"
- [(set_attr "type" "store")
- (set_attr "length" "4")])
-
-;; The definition of this insn does not really explain what it does,
-;; but it should suffice
-;; that anything generated as this insn will be recognized as one
-;; and that it will not successfully combine with anything.
-(define_expand "movstrsi"
- [(parallel [(set (match_operand:BLK 0 "" "")
- (match_operand:BLK 1 "" ""))
- (clobber (match_dup 7))
- (clobber (match_dup 8))
- (clobber (match_dup 4))
- (clobber (match_dup 5))
- (clobber (match_dup 6))
- (use (match_operand:SI 2 "arith_operand" ""))
- (use (match_operand:SI 3 "const_int_operand" ""))])]
- ""
- "
-{
- int size, align;
-
- /* HP provides very fast block move library routine for the PA;
- this routine includes:
-
- 4x4 byte at a time block moves,
- 1x4 byte at a time with alignment checked at runtime with
- attempts to align the source and destination as needed
- 1x1 byte loop
-
- With that in mind, here's the heuristics to try and guess when
- the inlined block move will be better than the library block
- move:
-
- If the size isn't constant, then always use the library routines.
-
- If the size is large in respect to the known alignment, then use
- the library routines.
-
- If the size is small in repsect to the known alignment, then open
- code the copy (since that will lead to better scheduling).
-
- Else use the block move pattern. */
-
- /* Undetermined size, use the library routine. */
- if (GET_CODE (operands[2]) != CONST_INT)
- FAIL;
-
- size = INTVAL (operands[2]);
- align = INTVAL (operands[3]);
- align = align > 4 ? 4 : align;
-
- /* If size/alignment > 8 (eg size is large in respect to alignment),
- then use the library routines. */
- if (size / align > 16)
- FAIL;
-
- /* This does happen, but not often enough to worry much about. */
- if (size / align < MOVE_RATIO)
- FAIL;
-
- /* Fall through means we're going to use our block move pattern. */
- operands[0]
- = change_address (operands[0], VOIDmode,
- copy_to_mode_reg (SImode, XEXP (operands[0], 0)));
- operands[1]
- = change_address (operands[1], VOIDmode,
- copy_to_mode_reg (SImode, XEXP (operands[1], 0)));
- operands[4] = gen_reg_rtx (SImode);
- operands[5] = gen_reg_rtx (SImode);
- operands[6] = gen_reg_rtx (SImode);
- operands[7] = XEXP (operands[0], 0);
- operands[8] = XEXP (operands[1], 0);
-}")
-
-;; The operand constraints are written like this to support both compile-time
-;; and run-time determined byte count. If the count is run-time determined,
-;; the register with the byte count is clobbered by the copying code, and
-;; therefore it is forced to operand 2. If the count is compile-time
-;; determined, we need two scratch registers for the unrolled code.
-(define_insn "movstrsi_internal"
- [(set (mem:BLK (match_operand:SI 0 "register_operand" "+r,r"))
- (mem:BLK (match_operand:SI 1 "register_operand" "+r,r")))
- (clobber (match_dup 0))
- (clobber (match_dup 1))
- (clobber (match_operand:SI 2 "register_operand" "=r,r")) ;loop cnt/tmp
- (clobber (match_operand:SI 3 "register_operand" "=&r,&r")) ;item tmp
- (clobber (match_operand:SI 6 "register_operand" "=&r,&r")) ;item tmp2
- (use (match_operand:SI 4 "arith_operand" "J,2")) ;byte count
- (use (match_operand:SI 5 "const_int_operand" "n,n"))] ;alignment
- ""
- "* return output_block_move (operands, !which_alternative);"
- [(set_attr "type" "multi,multi")])
-
-;; Floating point move insns
-
-;; This pattern forces (set (reg:DF ...) (const_double ...))
-;; to be reloaded by putting the constant into memory when
-;; reg is a floating point register.
-;;
-;; For integer registers we use ldil;ldo to set the appropriate
-;; value.
-;;
-;; This must come before the movdf pattern, and it must be present
-;; to handle obscure reloading cases.
-(define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=?r,f")
- (match_operand:DF 1 "" "?F,m"))]
- "GET_CODE (operands[1]) == CONST_DOUBLE
- && operands[1] != CONST0_RTX (DFmode)
- && ! TARGET_SOFT_FLOAT"
- "* return (which_alternative == 0 ? output_move_double (operands)
- : \"fldd%F1 %1,%0\");"
- [(set_attr "type" "move,fpload")
- (set_attr "length" "16,4")])
-
-(define_expand "movdf"
- [(set (match_operand:DF 0 "general_operand" "")
- (match_operand:DF 1 "general_operand" ""))]
- ""
- "
-{
- if (emit_move_sequence (operands, DFmode, 0))
- DONE;
-}")
-
-;; Reloading an SImode or DImode value requires a scratch register if
-;; going in to or out of float point registers.
-
-(define_expand "reload_indf"
- [(set (match_operand:DF 0 "register_operand" "=Z")
- (match_operand:DF 1 "non_hard_reg_operand" ""))
- (clobber (match_operand:DF 2 "register_operand" "=&r"))]
- ""
- "
-{
- if (emit_move_sequence (operands, DFmode, operands[2]))
- DONE;
-
- /* We don't want the clobber emitted, so handle this ourselves. */
- emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
- DONE;
-}")
-
-(define_expand "reload_outdf"
- [(set (match_operand:DF 0 "non_hard_reg_operand" "")
- (match_operand:DF 1 "register_operand" "Z"))
- (clobber (match_operand:DF 2 "register_operand" "=&r"))]
- ""
- "
-{
- if (emit_move_sequence (operands, DFmode, operands[2]))
- DONE;
-
- /* We don't want the clobber emitted, so handle this ourselves. */
- emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
- DONE;
-}")
-
-(define_insn ""
- [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand"
- "=f,*r,RQ,?o,?Q,f,*r,*r")
- (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
- "fG,*rG,f,*r,*r,RQ,o,RQ"))]
- "(register_operand (operands[0], DFmode)
- || reg_or_0_operand (operands[1], DFmode))
- && ! (GET_CODE (operands[1]) == CONST_DOUBLE
- && GET_CODE (operands[0]) == MEM)
- && ! TARGET_SOFT_FLOAT"
- "*
-{
- if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])
- || operands[1] == CONST0_RTX (DFmode))
- return output_fp_move_double (operands);
- return output_move_double (operands);
-}"
- [(set_attr "type" "fpalu,move,fpstore,store,store,fpload,load,load")
- (set_attr "length" "4,8,4,8,16,4,8,16")])
-
-(define_insn ""
- [(set (match_operand:DF 0 "reg_or_nonsymb_mem_operand"
- "=r,?o,?Q,r,r")
- (match_operand:DF 1 "reg_or_0_or_nonsymb_mem_operand"
- "rG,r,r,o,Q"))]
- "(register_operand (operands[0], DFmode)
- || reg_or_0_operand (operands[1], DFmode))
- && TARGET_SOFT_FLOAT"
- "*
-{
- return output_move_double (operands);
-}"
- [(set_attr "type" "move,store,store,load,load")
- (set_attr "length" "8,8,16,8,16")])
-
-(define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=fx")
- (mem:DF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
- (match_operand:SI 2 "register_operand" "r"))))]
- "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
- "*
-{
- /* Reload can create backwards (relative to cse) unscaled index
- address modes when eliminating registers and possibly for
- pseudos that don't get hard registers. Deal with it. */
- if (operands[2] == hard_frame_pointer_rtx
- || operands[2] == stack_pointer_rtx)
- return \"flddx %1(0,%2),%0\";
- else
- return \"flddx %2(0,%1),%0\";
-}"
- [(set_attr "type" "fpload")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=fx")
- (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "basereg_operand" "r"))))]
- "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
- "*
-{
- /* Reload can create backwards (relative to cse) unscaled index
- address modes when eliminating registers and possibly for
- pseudos that don't get hard registers. Deal with it. */
- if (operands[1] == hard_frame_pointer_rtx
- || operands[1] == stack_pointer_rtx)
- return \"flddx %2(0,%1),%0\";
- else
- return \"flddx %1(0,%2),%0\";
-}"
- [(set_attr "type" "fpload")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (mem:DF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
- (match_operand:SI 2 "register_operand" "r")))
- (match_operand:DF 0 "register_operand" "fx"))]
- "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
- "*
-{
- /* Reload can create backwards (relative to cse) unscaled index
- address modes when eliminating registers and possibly for
- pseudos that don't get hard registers. Deal with it. */
- if (operands[2] == hard_frame_pointer_rtx
- || operands[2] == stack_pointer_rtx)
- return \"fstdx %0,%1(0,%2)\";
- else
- return \"fstdx %0,%2(0,%1)\";
-}"
- [(set_attr "type" "fpstore")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (mem:DF (plus:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "basereg_operand" "r")))
- (match_operand:DF 0 "register_operand" "fx"))]
- "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
- "*
-{
- /* Reload can create backwards (relative to cse) unscaled index
- address modes when eliminating registers and possibly for
- pseudos that don't get hard registers. Deal with it. */
- if (operands[1] == hard_frame_pointer_rtx
- || operands[1] == stack_pointer_rtx)
- return \"fstdx %0,%2(0,%1)\";
- else
- return \"fstdx %0,%1(0,%2)\";
-}"
- [(set_attr "type" "fpstore")
- (set_attr "length" "4")])
-
-(define_expand "movdi"
- [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand" "")
- (match_operand:DI 1 "general_operand" ""))]
- ""
- "
-{
- if (emit_move_sequence (operands, DImode, 0))
- DONE;
-}")
-
-(define_expand "reload_indi"
- [(set (match_operand:DI 0 "register_operand" "=f")
- (match_operand:DI 1 "non_hard_reg_operand" ""))
- (clobber (match_operand:SI 2 "register_operand" "=&r"))]
- ""
- "
-{
- if (emit_move_sequence (operands, DImode, operands[2]))
- DONE;
-
- /* We don't want the clobber emitted, so handle this ourselves. */
- emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
- DONE;
-}")
-
-(define_expand "reload_outdi"
- [(set (match_operand:DI 0 "general_operand" "")
- (match_operand:DI 1 "register_operand" "f"))
- (clobber (match_operand:SI 2 "register_operand" "=&r"))]
- ""
- "
-{
- if (emit_move_sequence (operands, DImode, operands[2]))
- DONE;
-
- /* We don't want the clobber emitted, so handle this ourselves. */
- emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
- DONE;
-}")
-
-(define_insn ""
- [(set (match_operand:DI 0 "register_operand" "=r")
- (high:DI (match_operand 1 "" "")))]
- ""
- "*
-{
- rtx op0 = operands[0];
- rtx op1 = operands[1];
-
- if (GET_CODE (op1) == CONST_INT)
- {
- operands[0] = operand_subword (op0, 1, 0, DImode);
- output_asm_insn (\"ldil L'%1,%0\", operands);
-
- operands[0] = operand_subword (op0, 0, 0, DImode);
- if (INTVAL (op1) < 0)
- output_asm_insn (\"ldi -1,%0\", operands);
- else
- output_asm_insn (\"ldi 0,%0\", operands);
- return \"\";
- }
- else if (GET_CODE (op1) == CONST_DOUBLE)
- {
- operands[0] = operand_subword (op0, 1, 0, DImode);
- operands[1] = GEN_INT (CONST_DOUBLE_LOW (op1));
- output_asm_insn (\"ldil L'%1,%0\", operands);
-
- operands[0] = operand_subword (op0, 0, 0, DImode);
- operands[1] = GEN_INT (CONST_DOUBLE_HIGH (op1));
- output_asm_insn (singlemove_string (operands), operands);
- return \"\";
- }
- else
- abort ();
-}"
- [(set_attr "type" "move")
- (set_attr "length" "8")])
-
-;;; Experimental
-
-(define_insn ""
- [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand"
- "=r,o,Q,r,r,r,f,f,*TR")
- (match_operand:DI 1 "general_operand"
- "rM,r,r,o*R,Q,i,fM,*TR,f"))]
- "(register_operand (operands[0], DImode)
- || reg_or_0_operand (operands[1], DImode))
- && ! TARGET_SOFT_FLOAT"
- "*
-{
- if (FP_REG_P (operands[0]) || FP_REG_P (operands[1])
- || (operands[1] == CONST0_RTX (DImode)))
- return output_fp_move_double (operands);
- return output_move_double (operands);
-}"
- [(set_attr "type" "move,store,store,load,load,multi,fpalu,fpload,fpstore")
- (set_attr "length" "8,8,16,8,16,16,4,4,4")])
-
-(define_insn ""
- [(set (match_operand:DI 0 "reg_or_nonsymb_mem_operand"
- "=r,o,Q,r,r,r")
- (match_operand:DI 1 "general_operand"
- "rM,r,r,o,Q,i"))]
- "(register_operand (operands[0], DImode)
- || reg_or_0_operand (operands[1], DImode))
- && TARGET_SOFT_FLOAT"
- "*
-{
- return output_move_double (operands);
-}"
- [(set_attr "type" "move,store,store,load,load,multi")
- (set_attr "length" "8,8,16,8,16,16")])
-
-(define_insn ""
- [(set (match_operand:DI 0 "register_operand" "=r,&r")
- (lo_sum:DI (match_operand:DI 1 "register_operand" "0,r")
- (match_operand:DI 2 "immediate_operand" "i,i")))]
- ""
- "*
-{
- /* Don't output a 64 bit constant, since we can't trust the assembler to
- handle it correctly. */
- if (GET_CODE (operands[2]) == CONST_DOUBLE)
- operands[2] = GEN_INT (CONST_DOUBLE_LOW (operands[2]));
- if (which_alternative == 1)
- output_asm_insn (\"copy %1,%0\", operands);
- return \"ldo R'%G2(%R1),%R0\";
-}"
- [(set_attr "type" "move,move")
- (set_attr "length" "4,8")])
-
-;; This pattern forces (set (reg:SF ...) (const_double ...))
-;; to be reloaded by putting the constant into memory when
-;; reg is a floating point register.
-;;
-;; For integer registers we use ldil;ldo to set the appropriate
-;; value.
-;;
-;; This must come before the movsf pattern, and it must be present
-;; to handle obscure reloading cases.
-(define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=?r,f")
- (match_operand:SF 1 "" "?F,m"))]
- "GET_CODE (operands[1]) == CONST_DOUBLE
- && operands[1] != CONST0_RTX (SFmode)
- && ! TARGET_SOFT_FLOAT"
- "* return (which_alternative == 0 ? singlemove_string (operands)
- : \" fldw%F1 %1,%0\");"
- [(set_attr "type" "move,fpload")
- (set_attr "length" "8,4")])
-
-(define_expand "movsf"
- [(set (match_operand:SF 0 "general_operand" "")
- (match_operand:SF 1 "general_operand" ""))]
- ""
- "
-{
- if (emit_move_sequence (operands, SFmode, 0))
- DONE;
-}")
-
-;; Reloading an SImode or DImode value requires a scratch register if
-;; going in to or out of float point registers.
-
-(define_expand "reload_insf"
- [(set (match_operand:SF 0 "register_operand" "=Z")
- (match_operand:SF 1 "non_hard_reg_operand" ""))
- (clobber (match_operand:SF 2 "register_operand" "=&r"))]
- ""
- "
-{
- if (emit_move_sequence (operands, SFmode, operands[2]))
- DONE;
-
- /* We don't want the clobber emitted, so handle this ourselves. */
- emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
- DONE;
-}")
-
-(define_expand "reload_outsf"
- [(set (match_operand:SF 0 "non_hard_reg_operand" "")
- (match_operand:SF 1 "register_operand" "Z"))
- (clobber (match_operand:SF 2 "register_operand" "=&r"))]
- ""
- "
-{
- if (emit_move_sequence (operands, SFmode, operands[2]))
- DONE;
-
- /* We don't want the clobber emitted, so handle this ourselves. */
- emit_insn (gen_rtx_SET (VOIDmode, operands[0], operands[1]));
- DONE;
-}")
-
-(define_insn ""
- [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand"
- "=f,r,f,r,RQ,Q")
- (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
- "fG,rG,RQ,RQ,f,rG"))]
- "(register_operand (operands[0], SFmode)
- || reg_or_0_operand (operands[1], SFmode))
- && ! TARGET_SOFT_FLOAT"
- "@
- fcpy,sgl %r1,%0
- copy %r1,%0
- fldw%F1 %1,%0
- ldw%M1 %1,%0
- fstw%F0 %r1,%0
- stw%M0 %r1,%0"
- [(set_attr "type" "fpalu,move,fpload,load,fpstore,store")
- (set_attr "pa_combine_type" "addmove")
- (set_attr "length" "4,4,4,4,4,4")])
-
-(define_insn ""
- [(set (match_operand:SF 0 "reg_or_nonsymb_mem_operand"
- "=r,r,Q")
- (match_operand:SF 1 "reg_or_0_or_nonsymb_mem_operand"
- "rG,RQ,rG"))]
- "(register_operand (operands[0], SFmode)
- || reg_or_0_operand (operands[1], SFmode))
- && TARGET_SOFT_FLOAT"
- "@
- copy %r1,%0
- ldw%M1 %1,%0
- stw%M0 %r1,%0"
- [(set_attr "type" "move,load,store")
- (set_attr "pa_combine_type" "addmove")
- (set_attr "length" "4,4,4")])
-
-(define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=fx")
- (mem:SF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
- (match_operand:SI 2 "register_operand" "r"))))]
- "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
- "*
-{
- /* Reload can create backwards (relative to cse) unscaled index
- address modes when eliminating registers and possibly for
- pseudos that don't get hard registers. Deal with it. */
- if (operands[2] == hard_frame_pointer_rtx
- || operands[2] == stack_pointer_rtx)
- return \"fldwx %1(0,%2),%0\";
- else
- return \"fldwx %2(0,%1),%0\";
-}"
- [(set_attr "type" "fpload")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=fx")
- (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "basereg_operand" "r"))))]
- "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
- "*
-{
- /* Reload can create backwards (relative to cse) unscaled index
- address modes when eliminating registers and possibly for
- pseudos that don't get hard registers. Deal with it. */
- if (operands[1] == hard_frame_pointer_rtx
- || operands[1] == stack_pointer_rtx)
- return \"fldwx %2(0,%1),%0\";
- else
- return \"fldwx %1(0,%2),%0\";
-}"
- [(set_attr "type" "fpload")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (mem:SF (plus:SI (match_operand:SI 1 "basereg_operand" "r")
- (match_operand:SI 2 "register_operand" "r")))
- (match_operand:SF 0 "register_operand" "fx"))]
- "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
- "*
-{
- /* Reload can create backwards (relative to cse) unscaled index
- address modes when eliminating registers and possibly for
- pseudos that don't get hard registers. Deal with it. */
- if (operands[2] == hard_frame_pointer_rtx
- || operands[2] == stack_pointer_rtx)
- return \"fstwx %0,%1(0,%2)\";
- else
- return \"fstwx %0,%2(0,%1)\";
-}"
- [(set_attr "type" "fpstore")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (mem:SF (plus:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "basereg_operand" "r")))
- (match_operand:SF 0 "register_operand" "fx"))]
- "! TARGET_DISABLE_INDEXING && ! TARGET_SOFT_FLOAT"
- "*
-{
- /* Reload can create backwards (relative to cse) unscaled index
- address modes when eliminating registers and possibly for
- pseudos that don't get hard registers. Deal with it. */
- if (operands[1] == hard_frame_pointer_rtx
- || operands[1] == stack_pointer_rtx)
- return \"fstwx %0,%2(0,%1)\";
- else
- return \"fstwx %0,%1(0,%2)\";
-}"
- [(set_attr "type" "fpstore")
- (set_attr "length" "4")])
-
-
-;;- zero extension instructions
-;; We have define_expand for zero extension patterns to make sure the
-;; operands get loaded into registers. The define_insns accept
-;; memory operands. This gives us better overall code than just
-;; having a pattern that does or does not accept memory operands.
-
-(define_expand "zero_extendhisi2"
- [(set (match_operand:SI 0 "register_operand" "")
- (zero_extend:SI
- (match_operand:HI 1 "register_operand" "")))]
- ""
- "")
-
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (zero_extend:SI
- (match_operand:HI 1 "move_operand" "r,RQ")))]
- "GET_CODE (operands[1]) != CONST_INT"
- "@
- extru %1,31,16,%0
- ldh%M1 %1,%0"
- [(set_attr "type" "shift,load")
- (set_attr "length" "4,4")])
-
-(define_expand "zero_extendqihi2"
- [(set (match_operand:HI 0 "register_operand" "")
- (zero_extend:HI
- (match_operand:QI 1 "register_operand" "")))]
- ""
- "")
-
-(define_insn ""
- [(set (match_operand:HI 0 "register_operand" "=r,r")
- (zero_extend:HI
- (match_operand:QI 1 "move_operand" "r,RQ")))]
- "GET_CODE (operands[1]) != CONST_INT"
- "@
- extru %1,31,8,%0
- ldb%M1 %1,%0"
- [(set_attr "type" "shift,load")
- (set_attr "length" "4,4")])
-
-(define_expand "zero_extendqisi2"
- [(set (match_operand:SI 0 "register_operand" "")
- (zero_extend:SI
- (match_operand:QI 1 "register_operand" "")))]
- ""
- "")
-
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (zero_extend:SI
- (match_operand:QI 1 "move_operand" "r,RQ")))]
- "GET_CODE (operands[1]) != CONST_INT"
- "@
- extru %1,31,8,%0
- ldb%M1 %1,%0"
- [(set_attr "type" "shift,load")
- (set_attr "length" "4,4")])
-
-;;- sign extension instructions
-
-(define_insn "extendhisi2"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
- ""
- "extrs %1,31,16,%0"
- [(set_attr "type" "shift")
- (set_attr "length" "4")])
-
-(define_insn "extendqihi2"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
- ""
- "extrs %1,31,8,%0"
- [(set_attr "type" "shift")
- (set_attr "length" "4")])
-
-(define_insn "extendqisi2"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (sign_extend:SI (match_operand:QI 1 "register_operand" "r")))]
- ""
- "extrs %1,31,8,%0"
- [(set_attr "type" "shift")
- (set_attr "length" "4")])
-
-;; Conversions between float and double.
-
-(define_insn "extendsfdf2"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (float_extend:DF
- (match_operand:SF 1 "register_operand" "f")))]
- "! TARGET_SOFT_FLOAT"
- "fcnvff,sgl,dbl %1,%0"
- [(set_attr "type" "fpalu")
- (set_attr "length" "4")])
-
-(define_insn "truncdfsf2"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (float_truncate:SF
- (match_operand:DF 1 "register_operand" "f")))]
- "! TARGET_SOFT_FLOAT"
- "fcnvff,dbl,sgl %1,%0"
- [(set_attr "type" "fpalu")
- (set_attr "length" "4")])
-
-;; Conversion between fixed point and floating point.
-;; Note that among the fix-to-float insns
-;; the ones that start with SImode come first.
-;; That is so that an operand that is a CONST_INT
-;; (and therefore lacks a specific machine mode).
-;; will be recognized as SImode (which is always valid)
-;; rather than as QImode or HImode.
-
-;; This pattern forces (set (reg:SF ...) (float:SF (const_int ...)))
-;; to be reloaded by putting the constant into memory.
-;; It must come before the more general floatsisf2 pattern.
-(define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=f")
- (float:SF (match_operand:SI 1 "const_int_operand" "m")))]
- "! TARGET_SOFT_FLOAT"
- "fldw%F1 %1,%0\;fcnvxf,sgl,sgl %0,%0"
- [(set_attr "type" "fpalu")
- (set_attr "length" "8")])
-
-(define_insn "floatsisf2"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (float:SF (match_operand:SI 1 "register_operand" "f")))]
- "! TARGET_SOFT_FLOAT"
- "fcnvxf,sgl,sgl %1,%0"
- [(set_attr "type" "fpalu")
- (set_attr "length" "4")])
-
-
-;; This pattern forces (set (reg:DF ...) (float:DF (const_int ...)))
-;; to be reloaded by putting the constant into memory.
-;; It must come before the more general floatsidf2 pattern.
-(define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=f")
- (float:DF (match_operand:SI 1 "const_int_operand" "m")))]
- "! TARGET_SOFT_FLOAT"
- "fldw%F1 %1,%0\;fcnvxf,sgl,dbl %0,%0"
- [(set_attr "type" "fpalu")
- (set_attr "length" "8")])
-
-(define_insn "floatsidf2"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (float:DF (match_operand:SI 1 "register_operand" "f")))]
- "! TARGET_SOFT_FLOAT"
- "fcnvxf,sgl,dbl %1,%0"
- [(set_attr "type" "fpalu")
- (set_attr "length" "4")])
-
-;; CYGNUS LOCAL pa8000/law */
-(define_expand "floatunssisf2"
- [(set (subreg:SI (match_dup 2) 1)
- (match_operand:SI 1 "register_operand" ""))
- (set (subreg:SI (match_dup 2) 0)
- (const_int 0))
- (set (match_operand:SF 0 "register_operand" "")
- (float:SF (match_dup 2)))]
- "TARGET_SNAKE && ! TARGET_SOFT_FLOAT"
- "
-{
- if (TARGET_PARISC_2_0)
- {
- emit_insn (gen_floatunssisf2_pa20 (operands[0], operands[1]));
- DONE;
- }
- operands[2] = gen_reg_rtx (DImode);
-}")
-
-(define_expand "floatunssidf2"
- [(set (subreg:SI (match_dup 2) 1)
- (match_operand:SI 1 "register_operand" ""))
- (set (subreg:SI (match_dup 2) 0)
- (const_int 0))
- (set (match_operand:DF 0 "register_operand" "")
- (float:DF (match_dup 2)))]
- "TARGET_SNAKE && ! TARGET_SOFT_FLOAT"
- "
-{
- if (TARGET_PARISC_2_0)
- {
- emit_insn (gen_floatunssidf2_pa20 (operands[0], operands[1]));
- DONE;
- }
- operands[2] = gen_reg_rtx (DImode);
-}")
-;; END CYGNUS LOCAL
-
-(define_insn "floatdisf2"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (float:SF (match_operand:DI 1 "register_operand" "f")))]
- "TARGET_SNAKE && ! TARGET_SOFT_FLOAT"
- "fcnvxf,dbl,sgl %1,%0"
- [(set_attr "type" "fpalu")
- (set_attr "length" "4")])
-
-(define_insn "floatdidf2"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (float:DF (match_operand:DI 1 "register_operand" "f")))]
- "TARGET_SNAKE && ! TARGET_SOFT_FLOAT"
- "fcnvxf,dbl,dbl %1,%0"
- [(set_attr "type" "fpalu")
- (set_attr "length" "4")])
-
-;; Convert a float to an actual integer.
-;; Truncation is performed as part of the conversion.
-
-(define_insn "fix_truncsfsi2"
- [(set (match_operand:SI 0 "register_operand" "=f")
- (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
- "! TARGET_SOFT_FLOAT"
- "fcnvfxt,sgl,sgl %1,%0"
- [(set_attr "type" "fpalu")
- (set_attr "length" "4")])
-
-(define_insn "fix_truncdfsi2"
- [(set (match_operand:SI 0 "register_operand" "=f")
- (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
- "! TARGET_SOFT_FLOAT"
- "fcnvfxt,dbl,sgl %1,%0"
- [(set_attr "type" "fpalu")
- (set_attr "length" "4")])
-
-(define_insn "fix_truncsfdi2"
- [(set (match_operand:DI 0 "register_operand" "=f")
- (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
- "TARGET_SNAKE && ! TARGET_SOFT_FLOAT"
- "fcnvfxt,sgl,dbl %1,%0"
- [(set_attr "type" "fpalu")
- (set_attr "length" "4")])
-
-(define_insn "fix_truncdfdi2"
- [(set (match_operand:DI 0 "register_operand" "=f")
- (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
- "TARGET_SNAKE && ! TARGET_SOFT_FLOAT"
- "fcnvfxt,dbl,dbl %1,%0"
- [(set_attr "type" "fpalu")
- (set_attr "length" "4")])
-
-;; CYGNUS LOCAL pa8000/law
-(define_insn "floatunssidf2_pa20"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (unsigned_float:DF (match_operand:SI 1 "register_operand" "f")))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- "fcnvuf,sgl,dbl %1,%0"
- [(set_attr "type" "fpalu")
- (set_attr "length" "4")])
-
-(define_insn "floatunssisf2_pa20"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (unsigned_float:SF (match_operand:SI 1 "register_operand" "f")))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- "fcnvuf,sgl,sgl %1,%0"
- [(set_attr "type" "fpalu")
- (set_attr "length" "4")])
-
-(define_insn "floatunsdisf2"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (unsigned_float:SF (match_operand:DI 1 "register_operand" "f")))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- "fcnvuf,dbl,sgl %1,%0"
- [(set_attr "type" "fpalu")
- (set_attr "length" "4")])
-
-(define_insn "floatunsdidf2"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (unsigned_float:DF (match_operand:DI 1 "register_operand" "f")))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- "fcnvuf,dbl,dbl %1,%0"
- [(set_attr "type" "fpalu")
- (set_attr "length" "4")])
-
-(define_insn "fixuns_truncsfsi2"
- [(set (match_operand:SI 0 "register_operand" "=f")
- (unsigned_fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- "fcnvfut,sgl,sgl %1,%0"
- [(set_attr "type" "fpalu")
- (set_attr "length" "4")])
-
-(define_insn "fixuns_truncdfsi2"
- [(set (match_operand:SI 0 "register_operand" "=f")
- (unsigned_fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- "fcnvfut,dbl,sgl %1,%0"
- [(set_attr "type" "fpalu")
- (set_attr "length" "4")])
-
-(define_insn "fixuns_truncsfdi2"
- [(set (match_operand:DI 0 "register_operand" "=f")
- (unsigned_fix:DI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- "fcnvfut,sgl,dbl %1,%0"
- [(set_attr "type" "fpalu")
- (set_attr "length" "4")])
-
-(define_insn "fixuns_truncdfdi2"
- [(set (match_operand:DI 0 "register_operand" "=f")
- (unsigned_fix:DI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- "fcnvfut,dbl,dbl %1,%0"
- [(set_attr "type" "fpalu")
- (set_attr "length" "4")])
-;; END CYGNUS LOCAL
-
-;;- arithmetic instructions
-
-(define_insn "adddi3"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (plus:DI (match_operand:DI 1 "register_operand" "%r")
- (match_operand:DI 2 "arith11_operand" "rI")))]
- ""
- "*
-{
- if (GET_CODE (operands[2]) == CONST_INT)
- {
- if (INTVAL (operands[2]) >= 0)
- return \"addi %2,%R1,%R0\;addc %1,0,%0\";
- else
- return \"addi %2,%R1,%R0\;subb %1,0,%0\";
- }
- else
- return \"add %R2,%R1,%R0\;addc %2,%1,%0\";
-}"
- [(set_attr "type" "binary")
- (set_attr "length" "8")])
-
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (plus:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
- (match_operand:SI 2 "register_operand" "r")))]
- ""
- "uaddcm %2,%1,%0"
- [(set_attr "type" "binary")
- (set_attr "length" "4")])
-
-;; define_splits to optimize cases of adding a constant integer
-;; to a register when the constant does not fit in 14 bits. */
-(define_split
- [(set (match_operand:SI 0 "register_operand" "")
- (plus:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "const_int_operand" "")))
- (clobber (match_operand:SI 4 "register_operand" ""))]
- "! cint_ok_for_move (INTVAL (operands[2]))
- && VAL_14_BITS_P (INTVAL (operands[2]) >> 1)"
- [(set (match_dup 4) (plus:SI (match_dup 1) (match_dup 2)))
- (set (match_dup 0) (plus:SI (match_dup 4) (match_dup 3)))]
- "
-{
- int val = INTVAL (operands[2]);
- int low = (val < 0) ? -0x2000 : 0x1fff;
- int rest = val - low;
-
- operands[2] = GEN_INT (rest);
- operands[3] = GEN_INT (low);
-}")
-
-(define_split
- [(set (match_operand:SI 0 "register_operand" "")
- (plus:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "const_int_operand" "")))
- (clobber (match_operand:SI 4 "register_operand" ""))]
- "! cint_ok_for_move (INTVAL (operands[2]))"
- [(set (match_dup 4) (match_dup 2))
- (set (match_dup 0) (plus:SI (mult:SI (match_dup 4) (match_dup 3))
- (match_dup 1)))]
- "
-{
- HOST_WIDE_INT intval = INTVAL (operands[2]);
-
- /* Try dividing the constant by 2, then 4, and finally 8 to see
- if we can get a constant which can be loaded into a register
- in a single instruction (cint_ok_for_move).
-
- If that fails, try to negate the constant and subtract it
- from our input operand. */
- if (intval % 2 == 0 && cint_ok_for_move (intval / 2))
- {
- operands[2] = GEN_INT (intval / 2);
- operands[3] = GEN_INT (2);
- }
- else if (intval % 4 == 0 && cint_ok_for_move (intval / 4))
- {
- operands[2] = GEN_INT (intval / 4);
- operands[3] = GEN_INT (4);
- }
- else if (intval % 8 == 0 && cint_ok_for_move (intval / 8))
- {
- operands[2] = GEN_INT (intval / 8);
- operands[3] = GEN_INT (8);
- }
- else if (cint_ok_for_move (-intval))
- {
- emit_insn (gen_rtx_SET (VOIDmode, operands[4], GEN_INT (-intval)));
- emit_insn (gen_subsi3 (operands[0], operands[1], operands[4]));
- DONE;
- }
- else
- FAIL;
-}")
-
-(define_insn "addsi3"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (plus:SI (match_operand:SI 1 "register_operand" "%r,r")
- (match_operand:SI 2 "arith_operand" "r,J")))]
- ""
- "@
- addl %1,%2,%0
- ldo %2(%1),%0"
- [(set_attr "type" "binary,binary")
- (set_attr "pa_combine_type" "addmove")
- (set_attr "length" "4,4")])
-
-;; Disgusting kludge to work around reload bugs with frame pointer
-;; elimination. Similar to other magic reload patterns in the
-;; indexed memory operations.
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=&r")
- (plus:SI (plus:SI (match_operand:SI 1 "register_operand" "%r")
- (match_operand:SI 2 "register_operand" "r"))
- (match_operand:SI 3 "const_int_operand" "rL")))]
- "reload_in_progress"
- "*
-{
- if (GET_CODE (operands[3]) == CONST_INT)
- return \"ldo %3(%2),%0\;addl %1,%0,%0\";
- else
- return \"addl %3,%2,%0\;addl %1,%0,%0\";
-}"
- [(set_attr "type" "binary")
- (set_attr "length" "8")])
-
-(define_insn "subdi3"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (minus:DI (match_operand:DI 1 "register_operand" "r")
- (match_operand:DI 2 "register_operand" "r")))]
- ""
- "sub %R1,%R2,%R0\;subb %1,%2,%0"
- [(set_attr "type" "binary")
- (set_attr "length" "8")])
-
-;; CYGNUS LOCAL PA8000/law
-(define_expand "subsi3"
- [(set (match_operand:SI 0 "register_operand" "")
- (minus:SI (match_operand:SI 1 "arith11_operand" "")
- (match_operand:SI 2 "register_operand" "")))]
- ""
- "")
-
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (minus:SI (match_operand:SI 1 "arith11_operand" "r,I")
- (match_operand:SI 2 "register_operand" "r,r")))]
- "!TARGET_PARISC_2_0"
- "@
- sub %1,%2,%0
- subi %1,%2,%0"
- [(set_attr "type" "binary,binary")
- (set_attr "length" "4,4")])
-
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r,r,q")
- (minus:SI (match_operand:SI 1 "arith11_operand" "r,I,S")
- (match_operand:SI 2 "register_operand" "r,r,r")))]
- "TARGET_PARISC_2_0"
- "@
- sub %1,%2,%0
- subi %1,%2,%0
- mtsarcm %2"
- [(set_attr "type" "binary,binary,move")
- (set_attr "length" "4,4,4")])
-;; END CYGNUS LOCAL
-
-;; Clobbering a "register_operand" instead of a match_scratch
-;; in operand3 of millicode calls avoids spilling %r1 and
-;; produces better code.
-
-;; The mulsi3 insns set up registers for the millicode call.
-(define_expand "mulsi3"
- [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
- (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
- (parallel [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
- (clobber (match_dup 3))
- (clobber (reg:SI 26))
- (clobber (reg:SI 25))
- (clobber (reg:SI 31))])
- (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
- ""
- "
-{
- if (TARGET_SNAKE && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT)
- {
- rtx scratch = gen_reg_rtx (DImode);
- operands[1] = force_reg (SImode, operands[1]);
- operands[2] = force_reg (SImode, operands[2]);
- emit_insn (gen_umulsidi3 (scratch, operands[1], operands[2]));
- emit_insn (gen_rtx_SET (VOIDmode,
- operands[0],
- gen_rtx_SUBREG (SImode, scratch, 1)));
- DONE;
- }
- operands[3] = gen_reg_rtx (SImode);
-}")
-
-(define_insn "umulsidi3"
- [(set (match_operand:DI 0 "nonimmediate_operand" "=f")
- (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f"))
- (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "f"))))]
- "TARGET_SNAKE && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT"
- "xmpyu %1,%2,%0"
- [(set_attr "type" "fpmuldbl")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:DI 0 "nonimmediate_operand" "=f")
- (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "f"))
- (match_operand:DI 2 "uint32_operand" "f")))]
- "TARGET_SNAKE && ! TARGET_DISABLE_FPREGS && ! TARGET_SOFT_FLOAT"
- "xmpyu %1,%R2,%0"
- [(set_attr "type" "fpmuldbl")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (reg:SI 29) (mult:SI (reg:SI 26) (reg:SI 25)))
- (clobber (match_operand:SI 0 "register_operand" "=a"))
- (clobber (reg:SI 26))
- (clobber (reg:SI 25))
- (clobber (reg:SI 31))]
- ""
- "* return output_mul_insn (0, insn);"
- [(set_attr "type" "milli")
- (set (attr "length")
- (cond [
-;; Target (or stub) within reach
- (and (lt (plus (symbol_ref "total_code_bytes") (pc))
- (const_int 240000))
- (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
- (const_int 0)))
- (const_int 4)
-
-;; NO_SPACE_REGS
- (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
- (const_int 0))
- (const_int 8)
-
-;; Out of reach, but not PIC or PORTABLE_RUNTIME
-;; same as NO_SPACE_REGS code
- (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
- (const_int 0))
- (eq (symbol_ref "flag_pic")
- (const_int 0)))
- (const_int 8)]
-
-;; Out of range and either PIC or PORTABLE_RUNTIME
- (const_int 24)))])
-
-;;; Division and mod.
-(define_expand "divsi3"
- [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
- (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
- (parallel [(set (reg:SI 29) (div:SI (reg:SI 26) (reg:SI 25)))
- (clobber (match_dup 3))
- (clobber (reg:SI 26))
- (clobber (reg:SI 25))
- (clobber (reg:SI 31))])
- (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
- ""
- "
-{
- operands[3] = gen_reg_rtx (SImode);
- if (GET_CODE (operands[2]) == CONST_INT && emit_hpdiv_const (operands, 0))
- DONE;
-}")
-
-(define_insn ""
- [(set (reg:SI 29)
- (div:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
- (clobber (match_operand:SI 1 "register_operand" "=a"))
- (clobber (reg:SI 26))
- (clobber (reg:SI 25))
- (clobber (reg:SI 31))]
- ""
- "*
- return output_div_insn (operands, 0, insn);"
- [(set_attr "type" "milli")
- (set (attr "length")
- (cond [
-;; Target (or stub) within reach
- (and (lt (plus (symbol_ref "total_code_bytes") (pc))
- (const_int 240000))
- (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
- (const_int 0)))
- (const_int 4)
-
-;; NO_SPACE_REGS
- (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
- (const_int 0))
- (const_int 8)
-
-;; Out of reach, but not PIC or PORTABLE_RUNTIME
-;; same as NO_SPACE_REGS code
- (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
- (const_int 0))
- (eq (symbol_ref "flag_pic")
- (const_int 0)))
- (const_int 8)]
-
-;; Out of range and either PIC or PORTABLE_RUNTIME
- (const_int 24)))])
-
-(define_expand "udivsi3"
- [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
- (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
- (parallel [(set (reg:SI 29) (udiv:SI (reg:SI 26) (reg:SI 25)))
- (clobber (match_dup 3))
- (clobber (reg:SI 26))
- (clobber (reg:SI 25))
- (clobber (reg:SI 31))])
- (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
- ""
- "
-{
- operands[3] = gen_reg_rtx (SImode);
- if (GET_CODE (operands[2]) == CONST_INT && emit_hpdiv_const (operands, 1))
- DONE;
-}")
-
-(define_insn ""
- [(set (reg:SI 29)
- (udiv:SI (reg:SI 26) (match_operand:SI 0 "div_operand" "")))
- (clobber (match_operand:SI 1 "register_operand" "=a"))
- (clobber (reg:SI 26))
- (clobber (reg:SI 25))
- (clobber (reg:SI 31))]
- ""
- "*
- return output_div_insn (operands, 1, insn);"
- [(set_attr "type" "milli")
- (set (attr "length")
- (cond [
-;; Target (or stub) within reach
- (and (lt (plus (symbol_ref "total_code_bytes") (pc))
- (const_int 240000))
- (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
- (const_int 0)))
- (const_int 4)
-
-;; NO_SPACE_REGS
- (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
- (const_int 0))
- (const_int 8)
-
-;; Out of reach, but not PIC or PORTABLE_RUNTIME
-;; same as NO_SPACE_REGS code
- (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
- (const_int 0))
- (eq (symbol_ref "flag_pic")
- (const_int 0)))
- (const_int 8)]
-
-;; Out of range and either PIC or PORTABLE_RUNTIME
- (const_int 24)))])
-
-(define_expand "modsi3"
- [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
- (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
- (parallel [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
- (clobber (match_dup 3))
- (clobber (reg:SI 26))
- (clobber (reg:SI 25))
- (clobber (reg:SI 31))])
- (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
- ""
- "
-{
- operands[3] = gen_reg_rtx (SImode);
-}")
-
-(define_insn ""
- [(set (reg:SI 29) (mod:SI (reg:SI 26) (reg:SI 25)))
- (clobber (match_operand:SI 0 "register_operand" "=a"))
- (clobber (reg:SI 26))
- (clobber (reg:SI 25))
- (clobber (reg:SI 31))]
- ""
- "*
- return output_mod_insn (0, insn);"
- [(set_attr "type" "milli")
- (set (attr "length")
- (cond [
-;; Target (or stub) within reach
- (and (lt (plus (symbol_ref "total_code_bytes") (pc))
- (const_int 240000))
- (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
- (const_int 0)))
- (const_int 4)
-
-;; NO_SPACE_REGS
- (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
- (const_int 0))
- (const_int 8)
-
-;; Out of reach, but not PIC or PORTABLE_RUNTIME
-;; same as NO_SPACE_REGS code
- (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
- (const_int 0))
- (eq (symbol_ref "flag_pic")
- (const_int 0)))
- (const_int 8)]
-
-;; Out of range and either PIC or PORTABLE_RUNTIME
- (const_int 24)))])
-
-(define_expand "umodsi3"
- [(set (reg:SI 26) (match_operand:SI 1 "move_operand" ""))
- (set (reg:SI 25) (match_operand:SI 2 "move_operand" ""))
- (parallel [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
- (clobber (match_dup 3))
- (clobber (reg:SI 26))
- (clobber (reg:SI 25))
- (clobber (reg:SI 31))])
- (set (match_operand:SI 0 "general_operand" "") (reg:SI 29))]
- ""
- "
-{
- operands[3] = gen_reg_rtx (SImode);
-}")
-
-(define_insn ""
- [(set (reg:SI 29) (umod:SI (reg:SI 26) (reg:SI 25)))
- (clobber (match_operand:SI 0 "register_operand" "=a"))
- (clobber (reg:SI 26))
- (clobber (reg:SI 25))
- (clobber (reg:SI 31))]
- ""
- "*
- return output_mod_insn (1, insn);"
- [(set_attr "type" "milli")
- (set (attr "length")
- (cond [
-;; Target (or stub) within reach
- (and (lt (plus (symbol_ref "total_code_bytes") (pc))
- (const_int 240000))
- (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
- (const_int 0)))
- (const_int 4)
-
-;; NO_SPACE_REGS
- (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
- (const_int 0))
- (const_int 8)
-
-;; Out of reach, but not PIC or PORTABLE_RUNTIME
-;; same as NO_SPACE_REGS code
- (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
- (const_int 0))
- (eq (symbol_ref "flag_pic")
- (const_int 0)))
- (const_int 8)]
-
-;; Out of range and either PIC or PORTABLE_RUNTIME
- (const_int 24)))])
-
-;;- and instructions
-;; We define DImode `and` so with DImode `not` we can get
-;; DImode `andn`. Other combinations are possible.
-
-(define_expand "anddi3"
- [(set (match_operand:DI 0 "register_operand" "")
- (and:DI (match_operand:DI 1 "arith_double_operand" "")
- (match_operand:DI 2 "arith_double_operand" "")))]
- ""
- "
-{
- if (! register_operand (operands[1], DImode)
- || ! register_operand (operands[2], DImode))
- /* Let GCC break this into word-at-a-time operations. */
- FAIL;
-}")
-
-(define_insn ""
- [(set (match_operand:DI 0 "register_operand" "=r")
- (and:DI (match_operand:DI 1 "register_operand" "%r")
- (match_operand:DI 2 "register_operand" "r")))]
- ""
- "and %1,%2,%0\;and %R1,%R2,%R0"
- [(set_attr "type" "binary")
- (set_attr "length" "8")])
-
-; The ? for op1 makes reload prefer zdepi instead of loading a huge
-; constant with ldil;ldo.
-(define_insn "andsi3"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (and:SI (match_operand:SI 1 "register_operand" "%?r,0")
- (match_operand:SI 2 "and_operand" "rO,P")))]
- ""
- "* return output_and (operands); "
- [(set_attr "type" "binary,shift")
- (set_attr "length" "4,4")])
-
-(define_insn ""
- [(set (match_operand:DI 0 "register_operand" "=r")
- (and:DI (not:DI (match_operand:DI 1 "register_operand" "r"))
- (match_operand:DI 2 "register_operand" "r")))]
- ""
- "andcm %2,%1,%0\;andcm %R2,%R1,%R0"
- [(set_attr "type" "binary")
- (set_attr "length" "8")])
-
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
- (match_operand:SI 2 "register_operand" "r")))]
- ""
- "andcm %2,%1,%0"
- [(set_attr "type" "binary")
- (set_attr "length" "4")])
-
-(define_expand "iordi3"
- [(set (match_operand:DI 0 "register_operand" "")
- (ior:DI (match_operand:DI 1 "arith_double_operand" "")
- (match_operand:DI 2 "arith_double_operand" "")))]
- ""
- "
-{
- if (! register_operand (operands[1], DImode)
- || ! register_operand (operands[2], DImode))
- /* Let GCC break this into word-at-a-time operations. */
- FAIL;
-}")
-
-(define_insn ""
- [(set (match_operand:DI 0 "register_operand" "=r")
- (ior:DI (match_operand:DI 1 "register_operand" "%r")
- (match_operand:DI 2 "register_operand" "r")))]
- ""
- "or %1,%2,%0\;or %R1,%R2,%R0"
- [(set_attr "type" "binary")
- (set_attr "length" "8")])
-
-;; Need a define_expand because we've run out of CONST_OK... characters.
-(define_expand "iorsi3"
- [(set (match_operand:SI 0 "register_operand" "")
- (ior:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "arith32_operand" "")))]
- ""
- "
-{
- if (! (ior_operand (operands[2], SImode)
- || register_operand (operands[2], SImode)))
- operands[2] = force_reg (SImode, operands[2]);
-}")
-
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (ior:SI (match_operand:SI 1 "register_operand" "0,0")
- (match_operand:SI 2 "ior_operand" "M,i")))]
- ""
- "* return output_ior (operands); "
- [(set_attr "type" "binary,shift")
- (set_attr "length" "4,4")])
-
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (ior:SI (match_operand:SI 1 "register_operand" "%r")
- (match_operand:SI 2 "register_operand" "r")))]
- ""
- "or %1,%2,%0"
- [(set_attr "type" "binary")
- (set_attr "length" "4")])
-
-(define_expand "xordi3"
- [(set (match_operand:DI 0 "register_operand" "")
- (xor:DI (match_operand:DI 1 "arith_double_operand" "")
- (match_operand:DI 2 "arith_double_operand" "")))]
- ""
- "
-{
- if (! register_operand (operands[1], DImode)
- || ! register_operand (operands[2], DImode))
- /* Let GCC break this into word-at-a-time operations. */
- FAIL;
-}")
-
-(define_insn ""
- [(set (match_operand:DI 0 "register_operand" "=r")
- (xor:DI (match_operand:DI 1 "register_operand" "%r")
- (match_operand:DI 2 "register_operand" "r")))]
- ""
- "xor %1,%2,%0\;xor %R1,%R2,%R0"
- [(set_attr "type" "binary")
- (set_attr "length" "8")])
-
-(define_insn "xorsi3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (xor:SI (match_operand:SI 1 "register_operand" "%r")
- (match_operand:SI 2 "register_operand" "r")))]
- ""
- "xor %1,%2,%0"
- [(set_attr "type" "binary")
- (set_attr "length" "4")])
-
-(define_insn "negdi2"
- [(set (match_operand:DI 0 "register_operand" "=r")
- (neg:DI (match_operand:DI 1 "register_operand" "r")))]
- ""
- "sub 0,%R1,%R0\;subb 0,%1,%0"
- [(set_attr "type" "unary")
- (set_attr "length" "8")])
-
-(define_insn "negsi2"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (neg:SI (match_operand:SI 1 "register_operand" "r")))]
- ""
- "sub 0,%1,%0"
- [(set_attr "type" "unary")
- (set_attr "length" "4")])
-
-(define_expand "one_cmpldi2"
- [(set (match_operand:DI 0 "register_operand" "")
- (not:DI (match_operand:DI 1 "arith_double_operand" "")))]
- ""
- "
-{
- if (! register_operand (operands[1], DImode))
- FAIL;
-}")
-
-(define_insn ""
- [(set (match_operand:DI 0 "register_operand" "=r")
- (not:DI (match_operand:DI 1 "register_operand" "r")))]
- ""
- "uaddcm 0,%1,%0\;uaddcm 0,%R1,%R0"
- [(set_attr "type" "unary")
- (set_attr "length" "8")])
-
-(define_insn "one_cmplsi2"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (not:SI (match_operand:SI 1 "register_operand" "r")))]
- ""
- "uaddcm 0,%1,%0"
- [(set_attr "type" "unary")
- (set_attr "length" "4")])
-
-;; Floating point arithmetic instructions.
-
-(define_insn "adddf3"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (plus:DF (match_operand:DF 1 "register_operand" "f")
- (match_operand:DF 2 "register_operand" "f")))]
- "! TARGET_SOFT_FLOAT"
- "fadd,dbl %1,%2,%0"
- [(set_attr "type" "fpalu")
- (set_attr "pa_combine_type" "faddsub")
- (set_attr "length" "4")])
-
-(define_insn "addsf3"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (plus:SF (match_operand:SF 1 "register_operand" "f")
- (match_operand:SF 2 "register_operand" "f")))]
- "! TARGET_SOFT_FLOAT"
- "fadd,sgl %1,%2,%0"
- [(set_attr "type" "fpalu")
- (set_attr "pa_combine_type" "faddsub")
- (set_attr "length" "4")])
-
-(define_insn "subdf3"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (minus:DF (match_operand:DF 1 "register_operand" "f")
- (match_operand:DF 2 "register_operand" "f")))]
- "! TARGET_SOFT_FLOAT"
- "fsub,dbl %1,%2,%0"
- [(set_attr "type" "fpalu")
- (set_attr "pa_combine_type" "faddsub")
- (set_attr "length" "4")])
-
-(define_insn "subsf3"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (minus:SF (match_operand:SF 1 "register_operand" "f")
- (match_operand:SF 2 "register_operand" "f")))]
- "! TARGET_SOFT_FLOAT"
- "fsub,sgl %1,%2,%0"
- [(set_attr "type" "fpalu")
- (set_attr "pa_combine_type" "faddsub")
- (set_attr "length" "4")])
-
-(define_insn "muldf3"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (mult:DF (match_operand:DF 1 "register_operand" "f")
- (match_operand:DF 2 "register_operand" "f")))]
- "! TARGET_SOFT_FLOAT"
- "fmpy,dbl %1,%2,%0"
- [(set_attr "type" "fpmuldbl")
- (set_attr "pa_combine_type" "fmpy")
- (set_attr "length" "4")])
-
-(define_insn "mulsf3"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (mult:SF (match_operand:SF 1 "register_operand" "f")
- (match_operand:SF 2 "register_operand" "f")))]
- "! TARGET_SOFT_FLOAT"
- "fmpy,sgl %1,%2,%0"
- [(set_attr "type" "fpmulsgl")
- (set_attr "pa_combine_type" "fmpy")
- (set_attr "length" "4")])
-
-(define_insn "divdf3"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (div:DF (match_operand:DF 1 "register_operand" "f")
- (match_operand:DF 2 "register_operand" "f")))]
- "! TARGET_SOFT_FLOAT"
- "fdiv,dbl %1,%2,%0"
- [(set_attr "type" "fpdivdbl")
- (set_attr "length" "4")])
-
-(define_insn "divsf3"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (div:SF (match_operand:SF 1 "register_operand" "f")
- (match_operand:SF 2 "register_operand" "f")))]
- "! TARGET_SOFT_FLOAT"
- "fdiv,sgl %1,%2,%0"
- [(set_attr "type" "fpdivsgl")
- (set_attr "length" "4")])
-
-;; CYGNUS LOCAL pa8000/law
-(define_insn "negdf2"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (neg:DF (match_operand:DF 1 "register_operand" "f")))]
- "! TARGET_SOFT_FLOAT"
- "*
-{
- if (TARGET_PARISC_2_0)
- return \"fneg,dbl %1,%0\";
- return \"fsub,dbl 0,%1,%0\";
-}"
- [(set_attr "type" "fpalu")
- (set_attr "length" "4")])
-
-(define_insn "negsf2"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (neg:SF (match_operand:SF 1 "register_operand" "f")))]
- "! TARGET_SOFT_FLOAT"
- "*
-{
- if (TARGET_PARISC_2_0)
- return \"fneg,sgl %1,%0\";
- return \"fsub,sgl 0,%1,%0\";
-}"
- [(set_attr "type" "fpalu")
- (set_attr "length" "4")])
-;; END CYGNUS LOCAL
-
-(define_insn "absdf2"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (abs:DF (match_operand:DF 1 "register_operand" "f")))]
- "! TARGET_SOFT_FLOAT"
- "fabs,dbl %1,%0"
- [(set_attr "type" "fpalu")
- (set_attr "length" "4")])
-
-(define_insn "abssf2"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (abs:SF (match_operand:SF 1 "register_operand" "f")))]
- "! TARGET_SOFT_FLOAT"
- "fabs,sgl %1,%0"
- [(set_attr "type" "fpalu")
- (set_attr "length" "4")])
-
-;; CYGNUS LOCAL pa8000/law
-;; Simple fused multiply-add sequences.
-(define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=f")
- (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
- (match_operand:DF 2 "register_operand" "f"))
- (match_operand:DF 3 "register_operand" "f")))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- "fmpyfadd,dbl %1,%2,%3,%0"
- [(set_attr "type" "fpmuldbl")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=f")
- (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
- (match_operand:SF 2 "register_operand" "f"))
- (match_operand:SF 3 "register_operand" "f")))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- "fmpyfadd,sgl %1,%2,%3,%0"
- [(set_attr "type" "fpmuldbl")
- (set_attr "length" "4")])
-
-;; Generating a fused multiply sequence is a win for this case as it will
-;; reduce the latency for the fused case without impacting the plain
-;; multiply case.
-;;
-;; Similar possibilities exist for fnegabs, shadd and other insns which
-;; perform two operations with the result of the first feeding the second.
-(define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=f")
- (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
- (match_operand:DF 2 "register_operand" "f"))
- (match_operand:DF 3 "register_operand" "f")))
- (set (match_operand:DF 4 "register_operand" "=&f")
- (mult:DF (match_dup 1) (match_dup 2)))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- "#"
- [(set_attr "type" "fpmuldbl")
- (set_attr "length" "8")])
-
-;; We want to split this up during scheduling since we want both insns
-;; to schedule independently.
-(define_split
- [(set (match_operand:DF 0 "register_operand" "=f")
- (plus:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
- (match_operand:DF 2 "register_operand" "f"))
- (match_operand:DF 3 "register_operand" "f")))
- (set (match_operand:DF 4 "register_operand" "=&f")
- (mult:DF (match_dup 1) (match_dup 2)))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- [(set (match_dup 4) (mult:DF (match_dup 1) (match_dup 2)))
- (set (match_dup 0) (plus:DF (mult:DF (match_dup 1) (match_dup 2))
- (match_dup 3)))]
- "")
-
-(define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=f")
- (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
- (match_operand:SF 2 "register_operand" "f"))
- (match_operand:SF 3 "register_operand" "f")))
- (set (match_operand:SF 4 "register_operand" "=&f")
- (mult:SF (match_dup 1) (match_dup 2)))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- "#"
- [(set_attr "type" "fpmuldbl")
- (set_attr "length" "8")])
-
-;; We want to split this up during scheduling since we want both insns
-;; to schedule independently.
-(define_split
- [(set (match_operand:SF 0 "register_operand" "=f")
- (plus:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
- (match_operand:SF 2 "register_operand" "f"))
- (match_operand:SF 3 "register_operand" "f")))
- (set (match_operand:SF 4 "register_operand" "=&f")
- (mult:SF (match_dup 1) (match_dup 2)))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- [(set (match_dup 4) (mult:SF (match_dup 1) (match_dup 2)))
- (set (match_dup 0) (plus:SF (mult:SF (match_dup 1) (match_dup 2))
- (match_dup 3)))]
- "")
-
-;; Negating a multiply can be faked by adding zero in a fused multiply-add
-;; instruction.
-(define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=f")
- (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
- (match_operand:DF 2 "register_operand" "f"))))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- "fmpynfadd,dbl %1,%2,0,%0"
- [(set_attr "type" "fpmuldbl")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=f")
- (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
- (match_operand:SF 2 "register_operand" "f"))))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- "fmpynfadd,sgl %1,%2,0,%0"
- [(set_attr "type" "fpmuldbl")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=f")
- (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
- (match_operand:DF 2 "register_operand" "f"))))
- (set (match_operand:DF 3 "register_operand" "=&f")
- (mult:DF (match_dup 1) (match_dup 2)))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- "#"
- [(set_attr "type" "fpmuldbl")
- (set_attr "length" "8")])
-
-(define_split
- [(set (match_operand:DF 0 "register_operand" "=f")
- (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
- (match_operand:DF 2 "register_operand" "f"))))
- (set (match_operand:DF 3 "register_operand" "=&f")
- (mult:DF (match_dup 1) (match_dup 2)))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- [(set (match_dup 3) (mult:DF (match_dup 1) (match_dup 2)))
- (set (match_dup 0) (neg:DF (mult:DF (match_dup 1) (match_dup 2))))]
- "")
-
-(define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=f")
- (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
- (match_operand:SF 2 "register_operand" "f"))))
- (set (match_operand:SF 3 "register_operand" "=&f")
- (mult:SF (match_dup 1) (match_dup 2)))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- "#"
- [(set_attr "type" "fpmuldbl")
- (set_attr "length" "8")])
-
-(define_split
- [(set (match_operand:SF 0 "register_operand" "=f")
- (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
- (match_operand:SF 2 "register_operand" "f"))))
- (set (match_operand:SF 3 "register_operand" "=&f")
- (mult:SF (match_dup 1) (match_dup 2)))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- [(set (match_dup 3) (mult:SF (match_dup 1) (match_dup 2)))
- (set (match_dup 0) (neg:SF (mult:SF (match_dup 1) (match_dup 2))))]
- "")
-
-;; Now fused multiplies with the result of the multiply negated.
-(define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=f")
- (plus:DF (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
- (match_operand:DF 2 "register_operand" "f")))
- (match_operand:DF 3 "register_operand" "f")))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- "fmpynfadd,dbl %1,%2,%3,%0"
- [(set_attr "type" "fpmuldbl")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=f")
- (plus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
- (match_operand:SF 2 "register_operand" "f")))
- (match_operand:SF 3 "register_operand" "f")))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- "fmpynfadd,sgl %1,%2,%3,%0"
- [(set_attr "type" "fpmuldbl")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=f")
- (plus:DF (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
- (match_operand:DF 2 "register_operand" "f")))
- (match_operand:DF 3 "register_operand" "f")))
- (set (match_operand:DF 4 "register_operand" "=&f")
- (mult:DF (match_dup 1) (match_dup 2)))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- "#"
- [(set_attr "type" "fpmuldbl")
- (set_attr "length" "8")])
-
-(define_split
- [(set (match_operand:DF 0 "register_operand" "=f")
- (plus:DF (neg:DF (mult:DF (match_operand:DF 1 "register_operand" "f")
- (match_operand:DF 2 "register_operand" "f")))
- (match_operand:DF 3 "register_operand" "f")))
- (set (match_operand:DF 4 "register_operand" "=&f")
- (mult:DF (match_dup 1) (match_dup 2)))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- [(set (match_dup 4) (mult:DF (match_dup 1) (match_dup 2)))
- (set (match_dup 0) (plus:DF (neg:DF (mult:DF (match_dup 1) (match_dup 2)))
- (match_dup 3)))]
- "")
-
-(define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=f")
- (plus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
- (match_operand:SF 2 "register_operand" "f")))
- (match_operand:SF 3 "register_operand" "f")))
- (set (match_operand:SF 4 "register_operand" "=&f")
- (mult:SF (match_dup 1) (match_dup 2)))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- "#"
- [(set_attr "type" "fpmuldbl")
- (set_attr "length" "8")])
-
-(define_split
- [(set (match_operand:SF 0 "register_operand" "=f")
- (plus:SF (neg:SF (mult:SF (match_operand:SF 1 "register_operand" "f")
- (match_operand:SF 2 "register_operand" "f")))
- (match_operand:SF 3 "register_operand" "f")))
- (set (match_operand:SF 4 "register_operand" "=&f")
- (mult:SF (match_dup 1) (match_dup 2)))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- [(set (match_dup 4) (mult:SF (match_dup 1) (match_dup 2)))
- (set (match_dup 0) (plus:SF (neg:SF (mult:SF (match_dup 1) (match_dup 2)))
- (match_dup 3)))]
- "")
-
-;; Same thing, but using minus instead of negation
-(define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=f")
- (minus:DF (match_operand:DF 3 "register_operand" "f")
- (mult:DF (match_operand:DF 1 "register_operand" "f")
- (match_operand:DF 2 "register_operand" "f"))))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- "fmpynfadd,dbl %1,%2,%3,%0"
- [(set_attr "type" "fpmuldbl")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=f")
- (minus:SF (match_operand:SF 3 "register_operand" "f")
- (mult:SF (match_operand:SF 1 "register_operand" "f")
- (match_operand:SF 2 "register_operand" "f"))))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- "fmpynfadd,sgl %1,%2,%3,%0"
- [(set_attr "type" "fpmuldbl")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=f")
- (minus:DF (match_operand:DF 3 "register_operand" "f")
- (mult:DF (match_operand:DF 1 "register_operand" "f")
- (match_operand:DF 2 "register_operand" "f"))))
- (set (match_operand:DF 4 "register_operand" "=&f")
- (mult:DF (match_dup 1) (match_dup 2)))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- "#"
- [(set_attr "type" "fpmuldbl")
- (set_attr "length" "8")])
-
-(define_split
- [(set (match_operand:DF 0 "register_operand" "=f")
- (minus:DF (match_operand:DF 3 "register_operand" "f")
- (mult:DF (match_operand:DF 1 "register_operand" "f")
- (match_operand:DF 2 "register_operand" "f"))))
- (set (match_operand:DF 4 "register_operand" "=&f")
- (mult:DF (match_dup 1) (match_dup 2)))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- [(set (match_dup 4) (mult:DF (match_dup 1) (match_dup 2)))
- (set (match_dup 0) (minus:DF (match_dup 3)
- (mult:DF (match_dup 1) (match_dup 2))))]
- "")
-
-(define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=f")
- (minus:SF (match_operand:SF 3 "register_operand" "f")
- (mult:SF (match_operand:SF 1 "register_operand" "f")
- (match_operand:SF 2 "register_operand" "f"))))
- (set (match_operand:SF 4 "register_operand" "=&f")
- (mult:SF (match_dup 1) (match_dup 2)))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- "#"
- [(set_attr "type" "fpmuldbl")
- (set_attr "length" "8")])
-
-(define_split
- [(set (match_operand:SF 0 "register_operand" "=f")
- (minus:SF (match_operand:SF 3 "register_operand" "f")
- (mult:SF (match_operand:SF 1 "register_operand" "f")
- (match_operand:SF 2 "register_operand" "f"))))
- (set (match_operand:SF 4 "register_operand" "=&f")
- (mult:SF (match_dup 1) (match_dup 2)))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- [(set (match_dup 4) (mult:SF (match_dup 1) (match_dup 2)))
- (set (match_dup 0) (minus:SF (match_dup 3)
- (mult:SF (match_dup 1) (match_dup 2))))]
- "")
-
-;; And similarly for negation of an absolute value.
-(define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=f")
- (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- "fnegabs,dbl %1,%0"
- [(set_attr "type" "fpalu")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=f")
- (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- "fnegabs,sgl %1,%0"
- [(set_attr "type" "fpalu")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=f")
- (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))
- (set (match_operand:DF 2 "register_operand" "=&f") (abs:DF (match_dup 1)))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- "#"
- [(set_attr "type" "fpalu")
- (set_attr "length" "8")])
-
-(define_split
- [(set (match_operand:DF 0 "register_operand" "=f")
- (neg:DF (abs:DF (match_operand:DF 1 "register_operand" "f"))))
- (set (match_operand:DF 2 "register_operand" "=&f") (abs:DF (match_dup 1)))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- [(set (match_dup 2) (abs:DF (match_dup 1)))
- (set (match_dup 0) (neg:DF (abs:DF (match_dup 1))))]
- "")
-
-(define_insn ""
- [(set (match_operand:SF 0 "register_operand" "=f")
- (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))
- (set (match_operand:SF 2 "register_operand" "=&f") (abs:SF (match_dup 1)))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- "#"
- [(set_attr "type" "fpalu")
- (set_attr "length" "8")])
-
-(define_split
- [(set (match_operand:SF 0 "register_operand" "=f")
- (neg:SF (abs:SF (match_operand:SF 1 "register_operand" "f"))))
- (set (match_operand:SF 2 "register_operand" "=&f") (abs:SF (match_dup 1)))]
- "! TARGET_SOFT_FLOAT && TARGET_PARISC_2_0"
- [(set (match_dup 2) (abs:SF (match_dup 1)))
- (set (match_dup 0) (neg:SF (abs:SF (match_dup 1))))]
- "")
-
-;; END CYGNUS LOCAL
-
-(define_insn "sqrtdf2"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (sqrt:DF (match_operand:DF 1 "register_operand" "f")))]
- "! TARGET_SOFT_FLOAT"
- "fsqrt,dbl %1,%0"
- [(set_attr "type" "fpsqrtdbl")
- (set_attr "length" "4")])
-
-(define_insn "sqrtsf2"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (sqrt:SF (match_operand:SF 1 "register_operand" "f")))]
- "! TARGET_SOFT_FLOAT"
- "fsqrt,sgl %1,%0"
- [(set_attr "type" "fpsqrtsgl")
- (set_attr "length" "4")])
-
-;;- Shift instructions
-
-;; Optimized special case of shifting.
-
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
- (const_int 24)))]
- ""
- "ldb%M1 %1,%0"
- [(set_attr "type" "load")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
- (const_int 16)))]
- ""
- "ldh%M1 %1,%0"
- [(set_attr "type" "load")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r")
- (match_operand:SI 3 "shadd_operand" ""))
- (match_operand:SI 1 "register_operand" "r")))]
- ""
- "sh%O3addl %2,%1,%0"
- [(set_attr "type" "binary")
- (set_attr "length" "4")])
-
-;; This variant of the above insn can occur if the first operand
-;; is the frame pointer. This is a kludge, but there doesn't
-;; seem to be a way around it. Only recognize it while reloading.
-;; Note how operand 3 uses a predicate of "const_int_operand", but
-;; has constraints allowing a register. I don't know how this works,
-;; but it somehow makes sure that out-of-range constants are placed
-;; in a register which somehow magically is a "const_int_operand".
-;; (this was stolen from alpha.md, I'm not going to try and change it.
-
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=&r,r")
- (plus:SI (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r,r")
- (match_operand:SI 4 "shadd_operand" ""))
- (match_operand:SI 1 "register_operand" "r,r"))
- (match_operand:SI 3 "const_int_operand" "r,J")))]
- "reload_in_progress"
- "@
- sh%O4addl %2,%1,%0\;addl %3,%0,%0
- sh%O4addl %2,%1,%0\;ldo %3(%0),%0"
- [(set_attr "type" "multi")
- (set_attr "length" "8")])
-
-;; This anonymous pattern and splitter wins because it reduces the latency
-;; of the shadd sequence without increasing the latency of the shift.
-;;
-;; We want to make sure and split up the operations for the scheduler since
-;; these instructions can (and should) schedule independently.
-;;
-;; It would be clearer if combine used the same operator for both expressions,
-;; it's somewhat confusing to have a mult in ine operation and an ashift
-;; in the other.
-;;
-;; If this pattern is not split before register allocation, then we must expose
-;; the fact that operand 4 is set before operands 1, 2 and 3 have been read.
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r")
- (match_operand:SI 3 "shadd_operand" ""))
- (match_operand:SI 1 "register_operand" "r")))
- (set (match_operand:SI 4 "register_operand" "=&r")
- (ashift:SI (match_dup 2)
- (match_operand:SI 5 "const_int_operand" "i")))]
- "INTVAL (operands[5]) == exact_log2 (INTVAL (operands[3]))"
- "#"
- [(set_attr "type" "binary")
- (set_attr "length" "8")])
-
-(define_split
- [(set (match_operand:SI 0 "register_operand" "=r")
- (plus:SI (mult:SI (match_operand:SI 2 "register_operand" "r")
- (match_operand:SI 3 "shadd_operand" ""))
- (match_operand:SI 1 "register_operand" "r")))
- (set (match_operand:SI 4 "register_operand" "=&r")
- (ashift:SI (match_dup 2)
- (match_operand:SI 5 "const_int_operand" "i")))]
- "INTVAL (operands[5]) == exact_log2 (INTVAL (operands[3]))"
- [(set (match_dup 4) (ashift:SI (match_dup 2) (match_dup 5)))
- (set (match_dup 0) (plus:SI (mult:SI (match_dup 2) (match_dup 3))
- (match_dup 1)))]
- "")
-
-(define_expand "ashlsi3"
- [(set (match_operand:SI 0 "register_operand" "")
- (ashift:SI (match_operand:SI 1 "lhs_lshift_operand" "")
- (match_operand:SI 2 "arith32_operand" "")))]
- ""
- "
-{
- if (GET_CODE (operands[2]) != CONST_INT)
- {
- rtx temp = gen_reg_rtx (SImode);
- emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
- if (GET_CODE (operands[1]) == CONST_INT)
- emit_insn (gen_zvdep_imm (operands[0], operands[1], temp));
- else
- emit_insn (gen_zvdep32 (operands[0], operands[1], temp));
- DONE;
- }
- /* Make sure both inputs are not constants,
- there are no patterns for that. */
- operands[1] = force_reg (SImode, operands[1]);
-}")
-
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (ashift:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "const_int_operand" "n")))]
- ""
- "zdep %1,%P2,%L2,%0"
- [(set_attr "type" "shift")
- (set_attr "length" "4")])
-
-; Match cases of op1 a CONST_INT here that zvdep_imm doesn't handle.
-; Doing it like this makes slightly better code since reload can
-; replace a register with a known value in range -16..15 with a
-; constant. Ideally, we would like to merge zvdep32 and zvdep_imm,
-; but since we have no more CONST_OK... characters, that is not
-; possible.
-(define_insn "zvdep32"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (ashift:SI (match_operand:SI 1 "arith5_operand" "r,L")
- (minus:SI (const_int 31)
- (match_operand:SI 2 "register_operand" "q,q"))))]
- ""
- "@
- zvdep %1,32,%0
- zvdepi %1,32,%0"
- [(set_attr "type" "shift,shift")
- (set_attr "length" "4,4")])
-
-(define_insn "zvdep_imm"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (ashift:SI (match_operand:SI 1 "lhs_lshift_cint_operand" "")
- (minus:SI (const_int 31)
- (match_operand:SI 2 "register_operand" "q"))))]
- ""
- "*
-{
- int x = INTVAL (operands[1]);
- operands[2] = GEN_INT (4 + exact_log2 ((x >> 4) + 1));
- operands[1] = GEN_INT ((x & 0xf) - 0x10);
- return \"zvdepi %1,%2,%0\";
-}"
- [(set_attr "type" "shift")
- (set_attr "length" "4")])
-
-(define_insn "vdepi_ior"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (ior:SI (ashift:SI (match_operand:SI 1 "const_int_operand" "")
- (minus:SI (const_int 31)
- (match_operand:SI 2 "register_operand" "q")))
- (match_operand:SI 3 "register_operand" "0")))]
- ; accept ...0001...1, can this be generalized?
- "exact_log2 (INTVAL (operands[1]) + 1) >= 0"
- "*
-{
- int x = INTVAL (operands[1]);
- operands[2] = GEN_INT (exact_log2 (x + 1));
- return \"vdepi -1,%2,%0\";
-}"
- [(set_attr "type" "shift")
- (set_attr "length" "4")])
-
-(define_insn "vdepi_and"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (and:SI (rotate:SI (match_operand:SI 1 "const_int_operand" "")
- (minus:SI (const_int 31)
- (match_operand:SI 2 "register_operand" "q")))
- (match_operand:SI 3 "register_operand" "0")))]
- ; this can be generalized...!
- "INTVAL (operands[1]) == -2"
- "*
-{
- int x = INTVAL (operands[1]);
- operands[2] = GEN_INT (exact_log2 ((~x) + 1));
- return \"vdepi 0,%2,%0\";
-}"
- [(set_attr "type" "shift")
- (set_attr "length" "4")])
-
-(define_expand "ashrsi3"
- [(set (match_operand:SI 0 "register_operand" "")
- (ashiftrt:SI (match_operand:SI 1 "register_operand" "")
- (match_operand:SI 2 "arith32_operand" "")))]
- ""
- "
-{
- if (GET_CODE (operands[2]) != CONST_INT)
- {
- rtx temp = gen_reg_rtx (SImode);
- emit_insn (gen_subsi3 (temp, GEN_INT (31), operands[2]));
- emit_insn (gen_vextrs32 (operands[0], operands[1], temp));
- DONE;
- }
-}")
-
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "const_int_operand" "n")))]
- ""
- "extrs %1,%P2,%L2,%0"
- [(set_attr "type" "shift")
- (set_attr "length" "4")])
-
-(define_insn "vextrs32"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
- (minus:SI (const_int 31)
- (match_operand:SI 2 "register_operand" "q"))))]
- ""
- "vextrs %1,32,%0"
- [(set_attr "type" "shift")
- (set_attr "length" "4")])
-
-(define_insn "lshrsi3"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (lshiftrt:SI (match_operand:SI 1 "register_operand" "r,r")
- (match_operand:SI 2 "arith32_operand" "q,n")))]
- ""
- "@
- vshd 0,%1,%0
- extru %1,%P2,%L2,%0"
- [(set_attr "type" "shift")
- (set_attr "length" "4")])
-
-(define_insn "rotrsi3"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (rotatert:SI (match_operand:SI 1 "register_operand" "r,r")
- (match_operand:SI 2 "arith32_operand" "q,n")))]
- ""
- "*
-{
- if (GET_CODE (operands[2]) == CONST_INT)
- {
- operands[2] = GEN_INT (INTVAL (operands[2]) & 31);
- return \"shd %1,%1,%2,%0\";
- }
- else
- return \"vshd %1,%1,%0\";
-}"
- [(set_attr "type" "shift")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (match_operator:SI 5 "plus_xor_ior_operator"
- [(ashift:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 3 "const_int_operand" "n"))
- (lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
- (match_operand:SI 4 "const_int_operand" "n"))]))]
- "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
- "shd %1,%2,%4,%0"
- [(set_attr "type" "shift")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (match_operator:SI 5 "plus_xor_ior_operator"
- [(lshiftrt:SI (match_operand:SI 2 "register_operand" "r")
- (match_operand:SI 4 "const_int_operand" "n"))
- (ashift:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 3 "const_int_operand" "n"))]))]
- "INTVAL (operands[3]) + INTVAL (operands[4]) == 32"
- "shd %1,%2,%4,%0"
- [(set_attr "type" "shift")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (and:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "const_int_operand" ""))
- (match_operand:SI 3 "const_int_operand" "")))]
- "exact_log2 (1 + (INTVAL (operands[3]) >> (INTVAL (operands[2]) & 31))) >= 0"
- "*
-{
- int cnt = INTVAL (operands[2]) & 31;
- operands[3] = GEN_INT (exact_log2 (1 + (INTVAL (operands[3]) >> cnt)));
- operands[2] = GEN_INT (31 - cnt);
- return \"zdep %1,%2,%3,%0\";
-}"
- [(set_attr "type" "shift")
- (set_attr "length" "4")])
-
-;; Unconditional and other jump instructions.
-
-;; CYGNUS LOCAL PA8000/law
-(define_insn "return"
- [(return)]
- "hppa_can_use_return_insn_p ()"
- "*
-{
- if (TARGET_PARISC_2_0)
- return \"bve%* 0(%%r2)\";
- return \"bv%* 0(%%r2)\";
-}"
- [(set_attr "type" "branch")
- (set_attr "length" "4")])
-
-;; Use a different pattern for functions which have non-trivial
-;; epilogues so as not to confuse jump and reorg.
-(define_insn "return_internal"
- [(use (reg:SI 2))
- (return)]
- ""
- "*
-{
- if (TARGET_PARISC_2_0)
- return \"bve%* 0(%%r2)\";
- return \"bv%* 0(%%r2)\";
-}"
- [(set_attr "type" "branch")
- (set_attr "length" "4")])
-;; END CYGNUS LOCAL
-
-(define_expand "prologue"
- [(const_int 0)]
- ""
- "hppa_expand_prologue ();DONE;")
-
-(define_expand "epilogue"
- [(return)]
- ""
- "
-{
- /* Try to use the trivial return first. Else use the full
- epilogue. */
- if (hppa_can_use_return_insn_p ())
- emit_jump_insn (gen_return ());
- else
- {
- hppa_expand_epilogue ();
- emit_jump_insn (gen_return_internal ());
- }
- DONE;
-}")
-
-;; Special because we use the value placed in %r2 by the bl instruction
-;; from within its delay slot to set the value for the 2nd parameter to
-;; the call.
-(define_insn "call_profiler"
- [(unspec_volatile [(const_int 0)] 0)
- (use (match_operand:SI 0 "const_int_operand" ""))]
- ""
- "bl _mcount,%%r2\;ldo %0(%%r2),%%r25"
- [(set_attr "type" "multi")
- (set_attr "length" "8")])
-
-(define_insn "blockage"
- [(unspec_volatile [(const_int 2)] 0)]
- ""
- ""
- [(set_attr "length" "0")])
-
-(define_insn "jump"
- [(set (pc) (label_ref (match_operand 0 "" "")))]
- ""
- "*
-{
- extern int optimize;
-
- if (GET_MODE (insn) == SImode)
- return \"bl %l0,0%#\";
-
- /* An unconditional branch which can reach its target. */
- if (get_attr_length (insn) != 24
- && get_attr_length (insn) != 16)
- return \"bl%* %l0,0\";
-
- /* An unconditional branch which can not reach its target.
-
- We need to be able to use %r1 as a scratch register; however,
- we can never be sure whether or not it's got a live value in
- it. Therefore, we must restore its original value after the
- jump.
-
- To make matters worse, we don't have a stack slot which we
- can always clobber. sp-12/sp-16 shouldn't ever have a live
- value during a non-optimizing compilation, so we use those
- slots for now. We don't support very long branches when
- optimizing -- they should be quite rare when optimizing.
-
- Really the way to go long term is a register scavenger; goto
- the target of the jump and find a register which we can use
- as a scratch to hold the value in %r1. */
-
- /* We don't know how to register scavenge yet. */
- if (optimize)
- abort ();
-
- /* First store %r1 into the stack. */
- output_asm_insn (\"stw %%r1,-16(%%r30)\", operands);
-
- /* Now load the target address into %r1 and do an indirect jump
- to the value specified in %r1. Be careful to generate PIC
- code as needed. */
- if (flag_pic)
- {
- rtx xoperands[2];
- xoperands[0] = operands[0];
- xoperands[1] = gen_label_rtx ();
-
- output_asm_insn (\"bl .+8,%%r1\\n\\taddil L'%l0-%l1,%%r1\", xoperands);
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
- CODE_LABEL_NUMBER (xoperands[1]));
- output_asm_insn (\"ldo R'%l0-%l1(%%r1),%%r1\\n\\tbv 0(%%r1)\",
- xoperands);
- }
- else
- output_asm_insn (\"ldil L'%l0,%%r1\\n\\tbe R'%l0(%%sr4,%%r1)\", operands);;
-
- /* And restore the value of %r1 in the delay slot. We're not optimizing,
- so we know nothing else can be in the delay slot. */
- return \"ldw -16(%%r30),%%r1\";
-}"
- [(set_attr "type" "uncond_branch")
- (set_attr "pa_combine_type" "uncond_branch")
- (set (attr "length")
- (cond [(eq (symbol_ref "jump_in_call_delay (insn)") (const_int 1))
- (if_then_else (lt (abs (minus (match_dup 0)
- (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8))
- (ge (abs (minus (match_dup 0) (plus (pc) (const_int 8))))
- (const_int 262100))
- (if_then_else (eq (symbol_ref "flag_pic") (const_int 0))
- (const_int 16)
- (const_int 24))]
- (const_int 4)))])
-
-;; Subroutines of "casesi".
-;; operand 0 is index
-;; operand 1 is the minimum bound
-;; operand 2 is the maximum bound - minimum bound + 1
-;; operand 3 is CODE_LABEL for the table;
-;; operand 4 is the CODE_LABEL to go to if index out of range.
-
-(define_expand "casesi"
- [(match_operand:SI 0 "general_operand" "")
- (match_operand:SI 1 "const_int_operand" "")
- (match_operand:SI 2 "const_int_operand" "")
- (match_operand 3 "" "")
- (match_operand 4 "" "")]
- ""
- "
-{
- if (GET_CODE (operands[0]) != REG)
- operands[0] = force_reg (SImode, operands[0]);
-
- if (operands[1] != const0_rtx)
- {
- rtx reg = gen_reg_rtx (SImode);
-
- operands[1] = GEN_INT (-INTVAL (operands[1]));
- if (!INT_14_BITS (operands[1]))
- operands[1] = force_reg (SImode, operands[1]);
- emit_insn (gen_addsi3 (reg, operands[0], operands[1]));
-
- operands[0] = reg;
- }
-
- if (!INT_5_BITS (operands[2]))
- operands[2] = force_reg (SImode, operands[2]);
-
- emit_insn (gen_cmpsi (operands[0], operands[2]));
- emit_jump_insn (gen_bgtu (operands[4]));
- if (TARGET_BIG_SWITCH)
- {
- rtx temp = gen_reg_rtx (SImode);
- emit_move_insn (temp, gen_rtx_PLUS (SImode, operands[0], operands[0]));
- operands[0] = temp;
- }
- emit_jump_insn (gen_casesi0 (operands[0], operands[3]));
- DONE;
-}")
-
-(define_insn "casesi0"
- [(set (pc) (plus:SI
- (mem:SI (plus:SI (pc)
- (match_operand:SI 0 "register_operand" "r")))
- (label_ref (match_operand 1 "" ""))))]
- ""
- "blr %0,0\;nop"
- [(set_attr "type" "multi")
- (set_attr "length" "8")])
-
-;; Need nops for the calls because execution is supposed to continue
-;; past; we don't want to nullify an instruction that we need.
-;;- jump to subroutine
-
-(define_expand "call"
- [(parallel [(call (match_operand:SI 0 "" "")
- (match_operand 1 "" ""))
- (clobber (reg:SI 2))])]
- ""
- "
-{
- rtx op;
- rtx call_insn;
-
- if (TARGET_PORTABLE_RUNTIME)
- op = force_reg (SImode, XEXP (operands[0], 0));
- else
- op = XEXP (operands[0], 0);
-
- /* Use two different patterns for calls to explicitly named functions
- and calls through function pointers. This is necessary as these two
- types of calls use different calling conventions, and CSE might try
- to change the named call into an indirect call in some cases (using
- two patterns keeps CSE from performing this optimization). */
- if (GET_CODE (op) == SYMBOL_REF)
- call_insn = emit_call_insn (gen_call_internal_symref (op, operands[1]));
- else
- {
- rtx tmpreg = gen_rtx_REG (SImode, 22);
- emit_move_insn (tmpreg, force_reg (SImode, op));
- call_insn = emit_call_insn (gen_call_internal_reg (operands[1]));
- }
-
- if (flag_pic)
- {
- use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
-
- /* After each call we must restore the PIC register, even if it
- doesn't appear to be used.
-
- This will set regs_ever_live for the callee saved register we
- stored the PIC register in. */
- emit_move_insn (pic_offset_table_rtx,
- gen_rtx_REG (SImode, PIC_OFFSET_TABLE_REGNUM_SAVED));
- emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
-
- /* Gross. We have to keep the scheduler from moving the restore
- of the PIC register away from the call. SCHED_GROUP_P is
- supposed to do this, but for some reason the compiler will
- go into an infinite loop when we use that.
-
- This method (blockage insn) may make worse code (then again
- it may not since calls are nearly blockages anyway), but at
- least it should work. */
- emit_insn (gen_blockage ());
- }
- DONE;
-}")
-
-(define_insn "call_internal_symref"
- [(call (mem:SI (match_operand:SI 0 "call_operand_address" ""))
- (match_operand 1 "" "i"))
- (clobber (reg:SI 2))
- (use (const_int 0))]
- "! TARGET_PORTABLE_RUNTIME"
- "*
-{
- output_arg_descriptor (insn);
- return output_call (insn, operands[0], gen_rtx_REG (SImode, 2));
-}"
- [(set_attr "type" "call")
- (set (attr "length")
-;; If we're sure that we can either reach the target or that the
-;; linker can use a long-branch stub, then the length is 4 bytes.
-;;
-;; For long-calls the length will be either 52 bytes (non-pic)
-;; or 68 bytes (pic). */
-;; Else we have to use a long-call;
- (if_then_else (lt (plus (symbol_ref "total_code_bytes") (pc))
- (const_int 240000))
- (const_int 4)
- (if_then_else (eq (symbol_ref "flag_pic")
- (const_int 0))
- (const_int 52)
- (const_int 68))))])
-
-(define_insn "call_internal_reg"
- [(call (mem:SI (reg:SI 22))
- (match_operand 0 "" "i"))
- (clobber (reg:SI 2))
- (use (const_int 1))]
- ""
- "*
-{
- rtx xoperands[2];
-
- /* First the special case for kernels, level 0 systems, etc. */
- if (TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS)
- return \"ble 0(%%sr4,%%r22)\;copy %%r31,%%r2\";
-
- /* Now the normal case -- we can reach $$dyncall directly or
- we're sure that we can get there via a long-branch stub.
-
- No need to check target flags as the length uniquely identifies
- the remaining cases. */
- if (get_attr_length (insn) == 8)
- return \".CALL\\tARGW0=GR\;bl $$dyncall,%%r31\;copy %%r31,%%r2\";
-
- /* Long millicode call, but we are not generating PIC or portable runtime
- code. */
- if (get_attr_length (insn) == 12)
- return \".CALL\\tARGW0=GR\;ldil L%%$$dyncall,%%r2\;ble R%%$$dyncall(%%sr4,%%r2)\;copy %%r31,%%r2\";
-
- /* Long millicode call for portable runtime. */
- if (get_attr_length (insn) == 20)
- return \"ldil L%%$$dyncall,%%r31\;ldo R%%$$dyncall(%%r31),%%r31\;blr 0,%%r2\;bv,n 0(%%r31)\;nop\";
-
- /* If we're generating PIC code. */
- xoperands[0] = operands[0];
- xoperands[1] = gen_label_rtx ();
- output_asm_insn (\"bl .+8,%%r1\", xoperands);
- output_asm_insn (\"addil L%%$$dyncall-%1,%%r1\", xoperands);
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
- CODE_LABEL_NUMBER (xoperands[1]));
- output_asm_insn (\"ldo R%%$$dyncall-%1(%%r1),%%r1\", xoperands);
- output_asm_insn (\"blr 0,%%r2\", xoperands);
- output_asm_insn (\"bv,n 0(%%r1)\\n\\tnop\", xoperands);
- return \"\";
-}"
- [(set_attr "type" "dyncall")
- (set (attr "length")
- (cond [
-;; First NO_SPACE_REGS
- (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
- (const_int 0))
- (const_int 8)
-
-;; Target (or stub) within reach
- (and (lt (plus (symbol_ref "total_code_bytes") (pc))
- (const_int 240000))
- (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
- (const_int 0)))
- (const_int 8)
-
-;; Out of reach, but not PIC or PORTABLE_RUNTIME
- (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
- (const_int 0))
- (eq (symbol_ref "flag_pic")
- (const_int 0)))
- (const_int 12)
-
- (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
- (const_int 0))
- (const_int 20)]
-
-;; Out of range PIC case
- (const_int 24)))])
-
-(define_expand "call_value"
- [(parallel [(set (match_operand 0 "" "")
- (call (match_operand:SI 1 "" "")
- (match_operand 2 "" "")))
- (clobber (reg:SI 2))])]
- ""
- "
-{
- rtx op;
- rtx call_insn;
-
- if (TARGET_PORTABLE_RUNTIME)
- op = force_reg (SImode, XEXP (operands[1], 0));
- else
- op = XEXP (operands[1], 0);
-
- /* Use two different patterns for calls to explicitly named functions
- and calls through function pointers. This is necessary as these two
- types of calls use different calling conventions, and CSE might try
- to change the named call into an indirect call in some cases (using
- two patterns keeps CSE from performing this optimization). */
- if (GET_CODE (op) == SYMBOL_REF)
- call_insn = emit_call_insn (gen_call_value_internal_symref (operands[0],
- op,
- operands[2]));
- else
- {
- rtx tmpreg = gen_rtx_REG (SImode, 22);
- emit_move_insn (tmpreg, force_reg (SImode, op));
- call_insn = emit_call_insn (gen_call_value_internal_reg (operands[0],
- operands[2]));
- }
- if (flag_pic)
- {
- use_reg (&CALL_INSN_FUNCTION_USAGE (call_insn), pic_offset_table_rtx);
-
- /* After each call we must restore the PIC register, even if it
- doesn't appear to be used.
-
- This will set regs_ever_live for the callee saved register we
- stored the PIC register in. */
- emit_move_insn (pic_offset_table_rtx,
- gen_rtx_REG (SImode, PIC_OFFSET_TABLE_REGNUM_SAVED));
- emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
-
- /* Gross. We have to keep the scheduler from moving the restore
- of the PIC register away from the call. SCHED_GROUP_P is
- supposed to do this, but for some reason the compiler will
- go into an infinite loop when we use that.
-
- This method (blockage insn) may make worse code (then again
- it may not since calls are nearly blockages anyway), but at
- least it should work. */
- emit_insn (gen_blockage ());
- }
- DONE;
-}")
-
-(define_insn "call_value_internal_symref"
- [(set (match_operand 0 "" "=rf")
- (call (mem:SI (match_operand:SI 1 "call_operand_address" ""))
- (match_operand 2 "" "i")))
- (clobber (reg:SI 2))
- (use (const_int 0))]
- ;;- Don't use operand 1 for most machines.
- "! TARGET_PORTABLE_RUNTIME"
- "*
-{
- output_arg_descriptor (insn);
- return output_call (insn, operands[1], gen_rtx_REG (SImode, 2));
-}"
- [(set_attr "type" "call")
- (set (attr "length")
-;; If we're sure that we can either reach the target or that the
-;; linker can use a long-branch stub, then the length is 4 bytes.
-;;
-;; For long-calls the length will be either 52 bytes (non-pic)
-;; or 68 bytes (pic). */
-;; Else we have to use a long-call;
- (if_then_else (lt (plus (symbol_ref "total_code_bytes") (pc))
- (const_int 240000))
- (const_int 4)
- (if_then_else (eq (symbol_ref "flag_pic")
- (const_int 0))
- (const_int 52)
- (const_int 68))))])
-
-(define_insn "call_value_internal_reg"
- [(set (match_operand 0 "" "=rf")
- (call (mem:SI (reg:SI 22))
- (match_operand 1 "" "i")))
- (clobber (reg:SI 2))
- (use (const_int 1))]
- ""
- "*
-{
- rtx xoperands[2];
-
- /* First the special case for kernels, level 0 systems, etc. */
- if (TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS)
- return \"ble 0(%%sr4,%%r22)\;copy %%r31,%%r2\";
-
- /* Now the normal case -- we can reach $$dyncall directly or
- we're sure that we can get there via a long-branch stub.
-
- No need to check target flags as the length uniquely identifies
- the remaining cases. */
- if (get_attr_length (insn) == 8)
- return \".CALL\\tARGW0=GR\;bl $$dyncall,%%r31\;copy %%r31,%%r2\";
-
- /* Long millicode call, but we are not generating PIC or portable runtime
- code. */
- if (get_attr_length (insn) == 12)
- return \".CALL\\tARGW0=GR\;ldil L%%$$dyncall,%%r2\;ble R%%$$dyncall(%%sr4,%%r2)\;copy %%r31,%%r2\";
-
- /* Long millicode call for portable runtime. */
- if (get_attr_length (insn) == 20)
- return \"ldil L%%$$dyncall,%%r31\;ldo R%%$$dyncall(%%r31),%%r31\;blr 0,%%r2\;bv,n 0(%%r31)\;nop\";
-
- /* If we're generating PIC code. */
- xoperands[0] = operands[1];
- xoperands[1] = gen_label_rtx ();
- output_asm_insn (\"bl .+8,%%r1\", xoperands);
- output_asm_insn (\"addil L%%$$dyncall-%1,%%r1\", xoperands);
- ASM_OUTPUT_INTERNAL_LABEL (asm_out_file, \"L\",
- CODE_LABEL_NUMBER (xoperands[1]));
- output_asm_insn (\"ldo R%%$$dyncall-%1(%%r1),%%r1\", xoperands);
- output_asm_insn (\"blr 0,%%r2\", xoperands);
- output_asm_insn (\"bv,n 0(%%r1)\\n\\tnop\", xoperands);
- return \"\";
-}"
- [(set_attr "type" "dyncall")
- (set (attr "length")
- (cond [
-;; First NO_SPACE_REGS
- (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
- (const_int 0))
- (const_int 8)
-
-;; Target (or stub) within reach
- (and (lt (plus (symbol_ref "total_code_bytes") (pc))
- (const_int 240000))
- (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
- (const_int 0)))
- (const_int 8)
-
-;; Out of reach, but not PIC or PORTABLE_RUNTIME
- (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
- (const_int 0))
- (eq (symbol_ref "flag_pic")
- (const_int 0)))
- (const_int 12)
-
- (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
- (const_int 0))
- (const_int 20)]
-
-;; Out of range PIC case
- (const_int 24)))])
-
-;; Call subroutine returning any type.
-
-(define_expand "untyped_call"
- [(parallel [(call (match_operand 0 "" "")
- (const_int 0))
- (match_operand 1 "" "")
- (match_operand 2 "" "")])]
- ""
- "
-{
- int i;
-
- emit_call_insn (gen_call (operands[0], const0_rtx));
-
- for (i = 0; i < XVECLEN (operands[2], 0); i++)
- {
- rtx set = XVECEXP (operands[2], 0, i);
- emit_move_insn (SET_DEST (set), SET_SRC (set));
- }
-
- /* The optimizer does not know that the call sets the function value
- registers we stored in the result block. We avoid problems by
- claiming that all hard registers are used and clobbered at this
- point. */
- emit_insn (gen_blockage ());
-
- DONE;
-}")
-(define_insn "nop"
- [(const_int 0)]
- ""
- "nop"
- [(set_attr "type" "move")
- (set_attr "length" "4")])
-
-;; These are just placeholders so we know where branch tables
-;; begin and end.
-(define_insn "begin_brtab"
- [(const_int 1)]
- ""
- "*
-{
- /* Only GAS actually supports this pseudo-op. */
- if (TARGET_GAS)
- return \".begin_brtab\";
- else
- return \"\";
-}"
- [(set_attr "type" "move")
- (set_attr "length" "0")])
-
-(define_insn "end_brtab"
- [(const_int 2)]
- ""
- "*
-{
- /* Only GAS actually supports this pseudo-op. */
- if (TARGET_GAS)
- return \".end_brtab\";
- else
- return \"\";
-}"
- [(set_attr "type" "move")
- (set_attr "length" "0")])
-
-;;; Hope this is only within a function...
-(define_insn "indirect_jump"
- [(set (pc) (match_operand:SI 0 "register_operand" "r"))]
- ""
- "bv%* 0(%0)"
- [(set_attr "type" "branch")
- (set_attr "length" "4")])
-
-(define_insn "extzv"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "uint5_operand" "")
- (match_operand:SI 3 "uint5_operand" "")))]
- ""
- "extru %1,%3+%2-1,%2,%0"
- [(set_attr "type" "shift")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (zero_extract:SI (match_operand:SI 1 "register_operand" "r")
- (const_int 1)
- (match_operand:SI 3 "register_operand" "q")))]
- ""
- "vextru %1,1,%0"
- [(set_attr "type" "shift")
- (set_attr "length" "4")])
-
-(define_insn "extv"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "uint5_operand" "")
- (match_operand:SI 3 "uint5_operand" "")))]
- ""
- "extrs %1,%3+%2-1,%2,%0"
- [(set_attr "type" "shift")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (sign_extract:SI (match_operand:SI 1 "register_operand" "r")
- (const_int 1)
- (match_operand:SI 3 "register_operand" "q")))]
- ""
- "vextrs %1,1,%0"
- [(set_attr "type" "shift")
- (set_attr "length" "4")])
-
-(define_insn "insv"
- [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,r")
- (match_operand:SI 1 "uint5_operand" "")
- (match_operand:SI 2 "uint5_operand" ""))
- (match_operand:SI 3 "arith5_operand" "r,L"))]
- ""
- "@
- dep %3,%2+%1-1,%1,%0
- depi %3,%2+%1-1,%1,%0"
- [(set_attr "type" "shift,shift")
- (set_attr "length" "4,4")])
-
-;; Optimize insertion of const_int values of type 1...1xxxx.
-(define_insn ""
- [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
- (match_operand:SI 1 "uint5_operand" "")
- (match_operand:SI 2 "uint5_operand" ""))
- (match_operand:SI 3 "const_int_operand" ""))]
- "(INTVAL (operands[3]) & 0x10) != 0 &&
- (~INTVAL (operands[3]) & ((1L << INTVAL (operands[1])) - 1) & ~0xf) == 0"
- "*
-{
- operands[3] = GEN_INT ((INTVAL (operands[3]) & 0xf) - 0x10);
- return \"depi %3,%2+%1-1,%1,%0\";
-}"
- [(set_attr "type" "shift")
- (set_attr "length" "4")])
-
-;; This insn is used for some loop tests, typically loops reversed when
-;; strength reduction is used. It is actually created when the instruction
-;; combination phase combines the special loop test. Since this insn
-;; is both a jump insn and has an output, it must deal with its own
-;; reloads, hence the `m' constraints. The `!' constraints direct reload
-;; to not choose the register alternatives in the event a reload is needed.
-(define_insn "decrement_and_branch_until_zero"
- [(set (pc)
- (if_then_else
- (match_operator 2 "comparison_operator"
- [(plus:SI (match_operand:SI 0 "register_operand" "+!r,!*f,!*m")
- (match_operand:SI 1 "int5_operand" "L,L,L"))
- (const_int 0)])
- (label_ref (match_operand 3 "" ""))
- (pc)))
- (set (match_dup 0)
- (plus:SI (match_dup 0) (match_dup 1)))
- (clobber (match_scratch:SI 4 "=X,r,r"))]
- ""
- "* return output_dbra (operands, insn, which_alternative); "
-;; Do not expect to understand this the first time through.
-[(set_attr "type" "cbranch,multi,multi")
- (set (attr "length")
- (if_then_else (eq_attr "alternative" "0")
-;; Loop counter in register case
-;; Short branch has length of 4
-;; Long branch has length of 8
- (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8))
-
-;; Loop counter in FP reg case.
-;; Extra goo to deal with additional reload insns.
- (if_then_else (eq_attr "alternative" "1")
- (if_then_else (lt (match_dup 3) (pc))
- (if_then_else
- (lt (abs (minus (match_dup 3) (plus (pc) (const_int 24))))
- (const_int 8184))
- (const_int 24)
- (const_int 28))
- (if_then_else
- (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 24)
- (const_int 28)))
-;; Loop counter in memory case.
-;; Extra goo to deal with additional reload insns.
- (if_then_else (lt (match_dup 3) (pc))
- (if_then_else
- (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
- (const_int 8184))
- (const_int 12)
- (const_int 16))
- (if_then_else
- (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 12)
- (const_int 16))))))])
-
-(define_insn ""
- [(set (pc)
- (if_then_else
- (match_operator 2 "movb_comparison_operator"
- [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
- (label_ref (match_operand 3 "" ""))
- (pc)))
- (set (match_operand:SI 0 "register_operand" "=!r,!*f,!*m,!*q")
- (match_dup 1))]
- ""
-"* return output_movb (operands, insn, which_alternative, 0); "
-;; Do not expect to understand this the first time through.
-[(set_attr "type" "cbranch,multi,multi,multi")
- (set (attr "length")
- (if_then_else (eq_attr "alternative" "0")
-;; Loop counter in register case
-;; Short branch has length of 4
-;; Long branch has length of 8
- (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8))
-
-;; Loop counter in FP reg case.
-;; Extra goo to deal with additional reload insns.
- (if_then_else (eq_attr "alternative" "1")
- (if_then_else (lt (match_dup 3) (pc))
- (if_then_else
- (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
- (const_int 8184))
- (const_int 12)
- (const_int 16))
- (if_then_else
- (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 12)
- (const_int 16)))
-;; Loop counter in memory or sar case.
-;; Extra goo to deal with additional reload insns.
- (if_then_else
- (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 8)
- (const_int 12)))))])
-
-;; Handle negated branch.
-(define_insn ""
- [(set (pc)
- (if_then_else
- (match_operator 2 "movb_comparison_operator"
- [(match_operand:SI 1 "register_operand" "r,r,r,r") (const_int 0)])
- (pc)
- (label_ref (match_operand 3 "" ""))))
- (set (match_operand:SI 0 "register_operand" "=!r,!*f,!*m,!*q")
- (match_dup 1))]
- ""
-"* return output_movb (operands, insn, which_alternative, 1); "
-;; Do not expect to understand this the first time through.
-[(set_attr "type" "cbranch,multi,multi,multi")
- (set (attr "length")
- (if_then_else (eq_attr "alternative" "0")
-;; Loop counter in register case
-;; Short branch has length of 4
-;; Long branch has length of 8
- (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8))
-
-;; Loop counter in FP reg case.
-;; Extra goo to deal with additional reload insns.
- (if_then_else (eq_attr "alternative" "1")
- (if_then_else (lt (match_dup 3) (pc))
- (if_then_else
- (lt (abs (minus (match_dup 3) (plus (pc) (const_int 12))))
- (const_int 8184))
- (const_int 12)
- (const_int 16))
- (if_then_else
- (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 12)
- (const_int 16)))
-;; Loop counter in memory or SAR case.
-;; Extra goo to deal with additional reload insns.
- (if_then_else
- (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 8)
- (const_int 12)))))])
-
-;; The next several patterns (parallel_addb, parallel_movb, fmpyadd and
-;; fmpysub aren't currently used by the FSF sources, but will be soon.
-;;
-;; They're in the FSF tree for documentation and to make Cygnus<->FSF
-;; merging easier.
-(define_insn ""
- [(set (pc) (label_ref (match_operand 3 "" "" )))
- (set (match_operand:SI 0 "register_operand" "=r")
- (plus:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "ireg_or_int5_operand" "rL")))]
- "(reload_completed && operands[0] == operands[1]) || operands[0] == operands[2]"
- "*
-{
- return output_parallel_addb (operands, get_attr_length (insn));
-}"
- [(set_attr "type" "parallel_branch")
- (set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 3) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8)))])
-
-(define_insn ""
- [(set (pc) (label_ref (match_operand 2 "" "" )))
- (set (match_operand:SF 0 "register_operand" "=r")
- (match_operand:SF 1 "ireg_or_int5_operand" "rL"))]
- "reload_completed"
- "*
-{
- return output_parallel_movb (operands, get_attr_length (insn));
-}"
- [(set_attr "type" "parallel_branch")
- (set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8)))])
-
-(define_insn ""
- [(set (pc) (label_ref (match_operand 2 "" "" )))
- (set (match_operand:SI 0 "register_operand" "=r")
- (match_operand:SI 1 "ireg_or_int5_operand" "rL"))]
- "reload_completed"
- "*
-{
- return output_parallel_movb (operands, get_attr_length (insn));
-}"
- [(set_attr "type" "parallel_branch")
- (set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8)))])
-
-(define_insn ""
- [(set (pc) (label_ref (match_operand 2 "" "" )))
- (set (match_operand:HI 0 "register_operand" "=r")
- (match_operand:HI 1 "ireg_or_int5_operand" "rL"))]
- "reload_completed"
- "*
-{
- return output_parallel_movb (operands, get_attr_length (insn));
-}"
- [(set_attr "type" "parallel_branch")
- (set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8)))])
-
-(define_insn ""
- [(set (pc) (label_ref (match_operand 2 "" "" )))
- (set (match_operand:QI 0 "register_operand" "=r")
- (match_operand:QI 1 "ireg_or_int5_operand" "rL"))]
- "reload_completed"
- "*
-{
- return output_parallel_movb (operands, get_attr_length (insn));
-}"
- [(set_attr "type" "parallel_branch")
- (set (attr "length")
- (if_then_else (lt (abs (minus (match_dup 2) (plus (pc) (const_int 8))))
- (const_int 8184))
- (const_int 4)
- (const_int 8)))])
-
-(define_insn ""
- [(set (match_operand 0 "register_operand" "=f")
- (mult (match_operand 1 "register_operand" "f")
- (match_operand 2 "register_operand" "f")))
- (set (match_operand 3 "register_operand" "+f")
- (plus (match_operand 4 "register_operand" "f")
- (match_operand 5 "register_operand" "f")))]
- "TARGET_SNAKE && ! TARGET_SOFT_FLOAT
- && reload_completed && fmpyaddoperands (operands)"
- "*
-{
- if (GET_MODE (operands[0]) == DFmode)
- {
- if (rtx_equal_p (operands[3], operands[5]))
- return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
- else
- return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
- }
- else
- {
- if (rtx_equal_p (operands[3], operands[5]))
- return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
- else
- return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
- }
-}"
- [(set_attr "type" "fpalu")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand 3 "register_operand" "+f")
- (plus (match_operand 4 "register_operand" "f")
- (match_operand 5 "register_operand" "f")))
- (set (match_operand 0 "register_operand" "=f")
- (mult (match_operand 1 "register_operand" "f")
- (match_operand 2 "register_operand" "f")))]
- "TARGET_SNAKE && ! TARGET_SOFT_FLOAT
- && reload_completed && fmpyaddoperands (operands)"
- "*
-{
- if (GET_MODE (operands[0]) == DFmode)
- {
- if (rtx_equal_p (operands[3], operands[5]))
- return \"fmpyadd,dbl %1,%2,%0,%4,%3\";
- else
- return \"fmpyadd,dbl %1,%2,%0,%5,%3\";
- }
- else
- {
- if (rtx_equal_p (operands[3], operands[5]))
- return \"fmpyadd,sgl %1,%2,%0,%4,%3\";
- else
- return \"fmpyadd,sgl %1,%2,%0,%5,%3\";
- }
-}"
- [(set_attr "type" "fpalu")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand 0 "register_operand" "=f")
- (mult (match_operand 1 "register_operand" "f")
- (match_operand 2 "register_operand" "f")))
- (set (match_operand 3 "register_operand" "+f")
- (minus (match_operand 4 "register_operand" "f")
- (match_operand 5 "register_operand" "f")))]
- "TARGET_SNAKE && ! TARGET_SOFT_FLOAT
- && reload_completed && fmpysuboperands (operands)"
- "*
-{
- if (GET_MODE (operands[0]) == DFmode)
- return \"fmpysub,dbl %1,%2,%0,%5,%3\";
- else
- return \"fmpysub,sgl %1,%2,%0,%5,%3\";
-}"
- [(set_attr "type" "fpalu")
- (set_attr "length" "4")])
-
-(define_insn ""
- [(set (match_operand 3 "register_operand" "+f")
- (minus (match_operand 4 "register_operand" "f")
- (match_operand 5 "register_operand" "f")))
- (set (match_operand 0 "register_operand" "=f")
- (mult (match_operand 1 "register_operand" "f")
- (match_operand 2 "register_operand" "f")))]
- "TARGET_SNAKE && ! TARGET_SOFT_FLOAT
- && reload_completed && fmpysuboperands (operands)"
- "*
-{
- if (GET_MODE (operands[0]) == DFmode)
- return \"fmpysub,dbl %1,%2,%0,%5,%3\";
- else
- return \"fmpysub,sgl %1,%2,%0,%5,%3\";
-}"
- [(set_attr "type" "fpalu")
- (set_attr "length" "4")])
-
-;; Clean up turds left by reload.
-(define_peephole
- [(set (match_operand 0 "reg_or_nonsymb_mem_operand" "")
- (match_operand 1 "register_operand" "fr"))
- (set (match_operand 2 "register_operand" "fr")
- (match_dup 0))]
- "! TARGET_SOFT_FLOAT
- && GET_CODE (operands[0]) == MEM
- && ! MEM_VOLATILE_P (operands[0])
- && GET_MODE (operands[0]) == GET_MODE (operands[1])
- && GET_MODE (operands[0]) == GET_MODE (operands[2])
- && GET_MODE (operands[0]) == DFmode
- && GET_CODE (operands[1]) == REG
- && GET_CODE (operands[2]) == REG
- && ! side_effects_p (XEXP (operands[0], 0))
- && REGNO_REG_CLASS (REGNO (operands[1]))
- == REGNO_REG_CLASS (REGNO (operands[2]))"
- "*
-{
- rtx xoperands[2];
-
- if (FP_REG_P (operands[1]))
- output_asm_insn (output_fp_move_double (operands), operands);
- else
- output_asm_insn (output_move_double (operands), operands);
-
- if (rtx_equal_p (operands[1], operands[2]))
- return \"\";
-
- xoperands[0] = operands[2];
- xoperands[1] = operands[1];
-
- if (FP_REG_P (xoperands[1]))
- output_asm_insn (output_fp_move_double (xoperands), xoperands);
- else
- output_asm_insn (output_move_double (xoperands), xoperands);
-
- return \"\";
-}")
-
-(define_peephole
- [(set (match_operand 0 "register_operand" "fr")
- (match_operand 1 "reg_or_nonsymb_mem_operand" ""))
- (set (match_operand 2 "register_operand" "fr")
- (match_dup 1))]
- "! TARGET_SOFT_FLOAT
- && GET_CODE (operands[1]) == MEM
- && ! MEM_VOLATILE_P (operands[1])
- && GET_MODE (operands[0]) == GET_MODE (operands[1])
- && GET_MODE (operands[0]) == GET_MODE (operands[2])
- && GET_MODE (operands[0]) == DFmode
- && GET_CODE (operands[0]) == REG
- && GET_CODE (operands[2]) == REG
- && ! side_effects_p (XEXP (operands[1], 0))
- && REGNO_REG_CLASS (REGNO (operands[0]))
- == REGNO_REG_CLASS (REGNO (operands[2]))"
- "*
-{
- rtx xoperands[2];
-
- if (FP_REG_P (operands[0]))
- output_asm_insn (output_fp_move_double (operands), operands);
- else
- output_asm_insn (output_move_double (operands), operands);
-
- xoperands[0] = operands[2];
- xoperands[1] = operands[0];
-
- if (FP_REG_P (xoperands[1]))
- output_asm_insn (output_fp_move_double (xoperands), xoperands);
- else
- output_asm_insn (output_move_double (xoperands), xoperands);
-
- return \"\";
-}")
-
-;; Flush the I and D cache line found at the address in operand 0.
-;; This is used by the trampoline code for nested functions.
-;; So long as the trampoline itself is less than 32 bytes this
-;; is sufficient.
-
-(define_insn "dcacheflush"
- [(unspec_volatile [(const_int 1)] 0)
- (use (mem:SI (match_operand:SI 0 "register_operand" "r")))
- (use (mem:SI (match_operand:SI 1 "register_operand" "r")))]
- ""
- "fdc 0(0,%0)\;fdc 0(0,%1)\;sync"
- [(set_attr "type" "multi")
- (set_attr "length" "12")])
-
-(define_insn "icacheflush"
- [(unspec_volatile [(const_int 2)] 0)
- (use (mem:SI (match_operand:SI 0 "register_operand" "r")))
- (use (mem:SI (match_operand:SI 1 "register_operand" "r")))
- (use (match_operand:SI 2 "register_operand" "r"))
- (clobber (match_operand:SI 3 "register_operand" "=&r"))
- (clobber (match_operand:SI 4 "register_operand" "=&r"))]
- ""
- "mfsp %%sr0,%4\;ldsid (0,%2),%3\;mtsp %3,%%sr0\;fic 0(%%sr0,%0)\;fic 0(%%sr0,%1)\;sync\;mtsp %4,%%sr0\;nop\;nop\;nop\;nop\;nop\;nop"
- [(set_attr "type" "multi")
- (set_attr "length" "52")])
-
-;; An out-of-line prologue.
-(define_insn "outline_prologue_call"
- [(unspec_volatile [(const_int 0)] 0)
- (clobber (reg:SI 31))
- (clobber (reg:SI 22))
- (clobber (reg:SI 21))
- (clobber (reg:SI 20))
- (clobber (reg:SI 19))
- (clobber (reg:SI 1))]
- ""
- "*
-{
- extern int frame_pointer_needed;
-
- /* We need two different versions depending on whether or not we
- need a frame pointer. Also note that we return to the instruction
- immediately after the branch rather than two instructions after the
- break as normally is the case. */
- if (frame_pointer_needed)
- {
- /* Must import the magic millicode routine(s). */
- output_asm_insn (\".IMPORT __outline_prologue_fp,MILLICODE\", NULL);
-
- if (TARGET_PORTABLE_RUNTIME)
- {
- output_asm_insn (\"ldil L'__outline_prologue_fp,%%r31\", NULL);
- output_asm_insn (\"ble,n R'__outline_prologue_fp(%%sr0,%%r31)\",
- NULL);
- }
- else
- output_asm_insn (\"bl,n __outline_prologue_fp,%%r31\", NULL);
- }
- else
- {
- /* Must import the magic millicode routine(s). */
- output_asm_insn (\".IMPORT __outline_prologue,MILLICODE\", NULL);
-
- if (TARGET_PORTABLE_RUNTIME)
- {
- output_asm_insn (\"ldil L'__outline_prologue,%%r31\", NULL);
- output_asm_insn (\"ble,n R'__outline_prologue(%%sr0,%%r31)\", NULL);
- }
- else
- output_asm_insn (\"bl,n __outline_prologue,%%r31\", NULL);
- }
- return \"\";
-}"
- [(set_attr "type" "multi")
- (set_attr "length" "8")])
-
-;; An out-of-line epilogue.
-(define_insn "outline_epilogue_call"
- [(unspec_volatile [(const_int 1)] 0)
- (use (reg:SI 29))
- (use (reg:SI 28))
- (clobber (reg:SI 31))
- (clobber (reg:SI 22))
- (clobber (reg:SI 21))
- (clobber (reg:SI 20))
- (clobber (reg:SI 19))
- (clobber (reg:SI 2))
- (clobber (reg:SI 1))]
- ""
- "*
-{
- extern int frame_pointer_needed;
-
- /* We need two different versions depending on whether or not we
- need a frame pointer. Also note that we return to the instruction
- immediately after the branch rather than two instructions after the
- break as normally is the case. */
- if (frame_pointer_needed)
- {
- /* Must import the magic millicode routine. */
- output_asm_insn (\".IMPORT __outline_epilogue_fp,MILLICODE\", NULL);
-
- /* The out-of-line prologue will make sure we return to the right
- instruction. */
- if (TARGET_PORTABLE_RUNTIME)
- {
- output_asm_insn (\"ldil L'__outline_epilogue_fp,%%r31\", NULL);
- output_asm_insn (\"ble,n R'__outline_epilogue_fp(%%sr0,%%r31)\",
- NULL);
- }
- else
- output_asm_insn (\"bl,n __outline_epilogue_fp,%%r31\", NULL);
- }
- else
- {
- /* Must import the magic millicode routine. */
- output_asm_insn (\".IMPORT __outline_epilogue,MILLICODE\", NULL);
-
- /* The out-of-line prologue will make sure we return to the right
- instruction. */
- if (TARGET_PORTABLE_RUNTIME)
- {
- output_asm_insn (\"ldil L'__outline_epilogue,%%r31\", NULL);
- output_asm_insn (\"ble,n R'__outline_epilogue(%%sr0,%%r31)\", NULL);
- }
- else
- output_asm_insn (\"bl,n __outline_epilogue,%%r31\", NULL);
- }
- return \"\";
-}"
- [(set_attr "type" "multi")
- (set_attr "length" "8")])
-
-;; Given a function pointer, canonicalize it so it can be
-;; reliably compared to another function pointer. */
-(define_expand "canonicalize_funcptr_for_compare"
- [(set (reg:SI 26) (match_operand:SI 1 "register_operand" ""))
- (parallel [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] 0))
- (clobber (match_dup 2))
- (clobber (reg:SI 26))
- (clobber (reg:SI 22))
- (clobber (reg:SI 31))])
- (set (match_operand:SI 0 "register_operand" "")
- (reg:SI 29))]
- "! TARGET_PORTABLE_RUNTIME"
- "
-{
- operands[2] = gen_reg_rtx (SImode);
- if (GET_CODE (operands[1]) != REG)
- {
- rtx tmp = gen_reg_rtx (Pmode);
- emit_move_insn (tmp, operands[1]);
- operands[1] = tmp;
- }
-}")
-
-(define_insn ""
- [(set (reg:SI 29) (unspec:SI [(reg:SI 26)] 0))
- (clobber (match_operand:SI 0 "register_operand" "=a"))
- (clobber (reg:SI 26))
- (clobber (reg:SI 22))
- (clobber (reg:SI 31))]
- ""
- "*
-{
- /* Must import the magic millicode routine. */
- output_asm_insn (\".IMPORT $$sh_func_adrs,MILLICODE\", NULL);
-
- /* This is absolutely amazing.
-
- First, copy our input parameter into %r29 just in case we don't
- need to call $$sh_func_adrs. */
- output_asm_insn (\"copy %%r26,%%r29\", NULL);
-
- /* Next, examine the low two bits in %r26, if they aren't 0x2, then
- we use %r26 unchanged. */
- if (get_attr_length (insn) == 32)
- output_asm_insn (\"extru %%r26,31,2,%%r31\;comib,<>,n 2,%%r31,.+24\", NULL);
- else if (get_attr_length (insn) == 40)
- output_asm_insn (\"extru %%r26,31,2,%%r31\;comib,<>,n 2,%%r31,.+32\", NULL);
- else if (get_attr_length (insn) == 44)
- output_asm_insn (\"extru %%r26,31,2,%%r31\;comib,<>,n 2,%%r31,.+36\", NULL);
- else
- output_asm_insn (\"extru %%r26,31,2,%%r31\;comib,<>,n 2,%%r31,.+20\", NULL);
-
- /* Next, compare %r26 with 4096, if %r26 is less than or equal to
- 4096, then we use %r26 unchanged. */
- if (get_attr_length (insn) == 32)
- output_asm_insn (\"ldi 4096,%%r31\;comb,<<,n %%r26,%%r31,.+16\", NULL);
- else if (get_attr_length (insn) == 40)
- output_asm_insn (\"ldi 4096,%%r31\;comb,<<,n %%r26,%%r31,.+24\", NULL);
- else if (get_attr_length (insn) == 44)
- output_asm_insn (\"ldi 4096,%%r31\;comb,<<,n %%r26,%%r31,.+28\", NULL);
- else
- output_asm_insn (\"ldi 4096,%%r31\;comb,<<,n %%r26,%%r31,.+12\", NULL);
-
- /* Else call $$sh_func_adrs to extract the function's real add24. */
- return output_millicode_call (insn,
- gen_rtx_SYMBOL_REF (SImode, \"$$sh_func_adrs\"));
-}"
- [(set_attr "type" "multi")
- (set (attr "length")
- (cond [
-;; Target (or stub) within reach
- (and (lt (plus (symbol_ref "total_code_bytes") (pc))
- (const_int 240000))
- (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
- (const_int 0)))
- (const_int 28)
-
-;; NO_SPACE_REGS
- (ne (symbol_ref "TARGET_NO_SPACE_REGS || TARGET_FAST_INDIRECT_CALLS")
- (const_int 0))
- (const_int 32)
-
-;; Out of reach, but not PIC or PORTABLE_RUNTIME
-;; same as NO_SPACE_REGS code
- (and (eq (symbol_ref "TARGET_PORTABLE_RUNTIME")
- (const_int 0))
- (eq (symbol_ref "flag_pic")
- (const_int 0)))
- (const_int 32)
-
-;; PORTABLE_RUNTIME
- (ne (symbol_ref "TARGET_PORTABLE_RUNTIME")
- (const_int 0))
- (const_int 40)]
-
-;; Out of range and PIC
- (const_int 44)))])
-
-;; On the PA, the PIC register is call clobbered, so it must
-;; be saved & restored around calls by the caller. If the call
-;; doesn't return normally (nonlocal goto, or an exception is
-;; thrown), then the code at the exception handler label must
-;; restore the PIC register.
-(define_expand "exception_receiver"
- [(const_int 4)]
- "!TARGET_PORTABLE_RUNTIME && flag_pic"
- "
-{
- /* Load the PIC register from the stack slot (in our caller's
- frame). */
- emit_move_insn (pic_offset_table_rtx,
- gen_rtx_MEM (SImode, plus_constant (stack_pointer_rtx, -32)));
- emit_insn (gen_rtx_USE (VOIDmode, pic_offset_table_rtx));
- emit_insn (gen_blockage ());
- DONE;
-}")
-
-
diff --git a/gcc/config/pa/pa1.h b/gcc/config/pa/pa1.h
deleted file mode 100755
index 418de75..0000000
--- a/gcc/config/pa/pa1.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/* Definitions of target machine for GNU compiler, for HP PA-RISC 1.1
- Copyright (C) 1991 Free Software Foundation, Inc.
- Contributed by Tim Moore (moore@defmacro.cs.utah.edu)
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-#define TARGET_DEFAULT 0x89 /* TARGET_SNAKE + TARGET_GAS
- + TARGET_JUMP_IN_DELAY */
-
-/* This is the same as pa.h, except that we generate snake code by
- default. */
-
-#include "pa/pa.h"
diff --git a/gcc/config/pa/rtems.h b/gcc/config/pa/rtems.h
deleted file mode 100755
index a0d5b7a..0000000
--- a/gcc/config/pa/rtems.h
+++ /dev/null
@@ -1,31 +0,0 @@
-/* Definitions of target machine for GNU compiler, for PRO.
- Copyright (C) 1997 Free Software Foundation, Inc.
- Contributed by Joel Sherrill (joel@OARcorp.com).
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-/* Specify predefined symbols in preprocessor. */
-
-#undef CPP_PREDEFINES
-#define CPP_PREDEFINES "-Dhppa -DPWB -Acpu(hppa) -Amachine(hppa) \
- -Drtems -D__rtems__ -Asystem(rtems)"
-
-/* Generate calls to memcpy, memcmp and memset. */
-#ifndef TARGET_MEM_FUNCTIONS
-#define TARGET_MEM_FUNCTIONS
-#endif
diff --git a/gcc/config/pa/t-dce-thr b/gcc/config/pa/t-dce-thr
deleted file mode 100755
index 8d86a41..0000000
--- a/gcc/config/pa/t-dce-thr
+++ /dev/null
@@ -1,5 +0,0 @@
-MULTILIB_OPTIONS = threads
-MULTILIB_DIRNAMES = threads
-
-LIBGCC = stmp-multilib
-INSTALL_LIBGCC = install-multilib
diff --git a/gcc/config/pa/t-pa b/gcc/config/pa/t-pa
deleted file mode 100755
index a359918..0000000
--- a/gcc/config/pa/t-pa
+++ /dev/null
@@ -1,18 +0,0 @@
-LIBGCC1=libgcc1.null
-CROSS_LIBGCC1=libgcc1.null
-ADA_CFLAGS=-mdisable-indexing
-LIB2FUNCS_EXTRA=lib2funcs.asm ee.asm ee_fp.asm
-
-lib2funcs.asm: $(srcdir)/config/pa/lib2funcs.asm
- rm -f lib2funcs.asm
- cp $(srcdir)/config/pa/lib2funcs.asm .
-
-ee.asm: $(srcdir)/config/pa/ee.asm
- rm -f ee.asm
- cp $(srcdir)/config/pa/ee.asm .
-
-ee_fp.asm: $(srcdir)/config/pa/ee_fp.asm
- rm -f ee_fp.asm
- cp $(srcdir)/config/pa/ee_fp.asm .
-
-TARGET_LIBGCC2_CFLAGS = -fPIC
diff --git a/gcc/config/pa/t-pro b/gcc/config/pa/t-pro
deleted file mode 100755
index f40b2e4..0000000
--- a/gcc/config/pa/t-pro
+++ /dev/null
@@ -1,38 +0,0 @@
-LIBGCC1=libgcc1.null
-CROSS_LIBGCC1 = libgcc1.null
-LIB1ASMSRC =
-LIB1ASMFUNCS =
-
-LIBGCC1_TEST =
-
-ADA_CFLAGS=-mdisable-indexing
-
-LIB2FUNCS_EXTRA=fp-bit.c dp-bit.c lib2funcs.asm ee.asm ee_fp.asm
-
-dp-bit.c: $(srcdir)/config/fp-bit.c
- cat $(srcdir)/config/fp-bit.c > dp-bit.c
-
-fp-bit.c: $(srcdir)/config/fp-bit.c
- echo '#define FLOAT' > fp-bit.c
- cat $(srcdir)/config/fp-bit.c >> fp-bit.c
-
-lib2funcs.asm: $(srcdir)/config/pa/lib2funcs.asm
- rm -f lib2funcs.asm
- cp $(srcdir)/config/pa/lib2funcs.asm .
-
-ee.asm: $(srcdir)/config/pa/ee.asm
- rm -f ee.asm
- cp $(srcdir)/config/pa/ee.asm .
-
-ee_fp.asm: $(srcdir)/config/pa/ee_fp.asm
- rm -f ee_fp.asm
- cp $(srcdir)/config/pa/ee_fp.asm .
-
-# Build the libraries for both speed and space optimizations
-
-MULTILIB_OPTIONS=mspace
-MULTILIB_DIRNAMES=space
-MULTILIB_MATCHES=
-
-LIBGCC = stmp-multilib
-INSTALL_LIBGCC = install-multilib
diff --git a/gcc/config/pa/x-pa b/gcc/config/pa/x-pa
deleted file mode 100755
index 4c25047..0000000
--- a/gcc/config/pa/x-pa
+++ /dev/null
@@ -1,3 +0,0 @@
-# BSD on the PA already has ANSI include files which are c++ compatible.
-USER_H = $(EXTRA_HEADERS) $(LANG_EXTRA_HEADERS)
-STMP_FIXPROTO=
diff --git a/gcc/config/pa/x-pa-hpux b/gcc/config/pa/x-pa-hpux
deleted file mode 100755
index 1b8bb9f..0000000
--- a/gcc/config/pa/x-pa-hpux
+++ /dev/null
@@ -1,4 +0,0 @@
-ALLOCA=alloca.o
-
-# So putenv and other functions get seen by fixproto.
-FIXPROTO_DEFINES = -D_HPUX_SOURCE
diff --git a/gcc/config/pa/xm-pa.h b/gcc/config/pa/xm-pa.h
deleted file mode 100755
index 0249055..0000000
--- a/gcc/config/pa/xm-pa.h
+++ /dev/null
@@ -1,62 +0,0 @@
-/* Configuration for GNU C-compiler for PA-RISC.
- Copyright (C) 1988, 1995 Free Software Foundation, Inc.
- Contributed by Michael Tiemann (tiemann@cygnus.com).
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-extern int errno;
-
-/* #defines that need visibility everywhere. */
-#define FALSE 0
-#define TRUE 1
-
-/* This describes the machine the compiler is hosted on. */
-#define HOST_BITS_PER_CHAR 8
-#define HOST_BITS_PER_SHORT 16
-#define HOST_BITS_PER_INT 32
-#define HOST_BITS_PER_LONG 32
-#define HOST_BITS_PER_LONGLONG 64
-
-/* Doubles are stored in memory with the high order word first. This
- matters when cross-compiling. */
-#define HOST_WORDS_BIG_ENDIAN 1
-
-/* Place any machine-dependent include files here, in case we
- are bootstrapping. */
-
-/* target machine dependencies.
- tm.h is a symbolic link to the actual target specific file. */
-#include "tm.h"
-
-/* Arguments to use with `exit'. */
-#define SUCCESS_EXIT_CODE 0
-#define FATAL_EXIT_CODE 33
-
-/* Don't try to use sys_siglist. */
-#define NO_SYS_SIGLIST
-
-/* 4.3BSD, OSF1 and Lites on the PA are all derived from NET2 or
- later code from Berkeley. */
-#define __BSD_NET2__
-
-/* HP's compiler has problems with enum bitfields. */
-#define ONLY_INT_FIELDS
-
-/* Always claim to use C alloca; this prevents losing if building with
- gcc -fno-builtin ... */
-#define USE_C_ALLOCA
diff --git a/gcc/config/pa/xm-pahpux.h b/gcc/config/pa/xm-pahpux.h
deleted file mode 100755
index 09c949b..0000000
--- a/gcc/config/pa/xm-pahpux.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Configuration for GNU C-compiler for PA-RISC.
- Copyright (C) 1988, 1995, 1997 Free Software Foundation, Inc.
- Contributed by Michael Tiemann (tiemann@cygnus.com).
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-
-/* HP-UX is a flavor of System V */
-#define USG
-
-/* Use System V memory functions. */
-/* #defines that need visibility everywhere. */
-#define FALSE 0
-#define TRUE 1
-
-/* This describes the machine the compiler is hosted on. */
-#define HOST_BITS_PER_CHAR 8
-#define HOST_BITS_PER_SHORT 16
-#define HOST_BITS_PER_INT 32
-#define HOST_BITS_PER_LONG 32
-#define HOST_BITS_PER_LONGLONG 64
-
-/* Doubles are stored in memory with the high order word first. This
- matters when cross-compiling. */
-#define HOST_WORDS_BIG_ENDIAN 1
-
-/* Place any machine-dependent include files here, in case we
- are bootstrapping. */
-
-/* target machine dependencies.
- tm.h is a symbolic link to the actual target specific file. */
-#include "tm.h"
-
-/* Arguments to use with `exit'. */
-#define SUCCESS_EXIT_CODE 0
-#define FATAL_EXIT_CODE 33
-
-/* Don't try to use sys_siglist. */
-#define NO_SYS_SIGLIST
-
-/* HP's compiler has problems with enum bitfields. */
-#define ONLY_INT_FIELDS
-
-/* Always claim to use C alloca; this prevents losing if building with
- gcc -fno-builtin ... " */
-#define USE_C_ALLOCA
diff --git a/gcc/config/pa/xm-papro.h b/gcc/config/pa/xm-papro.h
deleted file mode 100755
index d36e201..0000000
--- a/gcc/config/pa/xm-papro.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/* Configuration for GNU C-compiler for PA-RISC.
- Copyright (C) 1994, 1995 Free Software Foundation, Inc.
- Contributed by Michael Tiemann (tiemann@cygnus.com).
-
-This file is part of GNU CC.
-
-GNU CC is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-GNU CC is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with GNU CC; see the file COPYING. If not, write to
-the Free Software Foundation, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA. */
-
-extern int errno;
-
-/* #defines that need visibility everywhere. */
-#define FALSE 0
-#define TRUE 1
-
-/* This describes the machine the compiler is hosted on. */
-#define HOST_BITS_PER_CHAR 8
-#define HOST_BITS_PER_SHORT 16
-#define HOST_BITS_PER_INT 32
-#define HOST_BITS_PER_LONG 32
-#define HOST_BITS_PER_LONGLONG 64
-
-/* Doubles are stored in memory with the high order word first. This
- matters when cross-compiling. */
-#define HOST_WORDS_BIG_ENDIAN 1
-
-/* Place any machine-dependent include files here, in case we
- are bootstrapping. */
-
-/* target machine dependencies.
- tm.h is a symbolic link to the actual target specific file. */
-#include "tm.h"
-
-/* Arguments to use with `exit'. */
-#define SUCCESS_EXIT_CODE 0
-#define FATAL_EXIT_CODE 33
-
-/* Don't try to use sys_siglist. */
-#define NO_SYS_SIGLIST
-
-/* HP's compiler has problems with enum bitfields. */
-#define ONLY_INT_FIELDS
-
-/* Always claim to use C alloca; this prevents losing if building with
- gcc -fno-builtin ... */
-#define USE_C_ALLOCA