home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 7
/
FreshFishVol7.bin
/
bbs
/
gnu
/
gcc-2.3.3-src.lha
/
GNU
/
src
/
amiga
/
gcc-2.3.3
/
config
/
vax.md
< prev
next >
Wrap
Text File
|
1994-02-06
|
57KB
|
2,034 lines
;;- Machine description for GNU compiler, Vax Version
;; Copyright (C) 1987, 1988, 1991 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, 675 Mass Ave, Cambridge, MA 02139, USA.
;;- Instruction patterns. When multiple patterns apply,
;;- the first one in the file is chosen.
;;-
;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
;;-
;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
;;- updates for most instructions.
;; We don't want to allow a constant operand for test insns because
;; (set (cc0) (const_int foo)) has no mode information. Such insns will
;; be folded while optimizing anyway.
(define_insn "tstsi"
[(set (cc0)
(match_operand:SI 0 "nonimmediate_operand" "g"))]
""
"tstl %0")
(define_insn "tsthi"
[(set (cc0)
(match_operand:HI 0 "nonimmediate_operand" "g"))]
""
"tstw %0")
(define_insn "tstqi"
[(set (cc0)
(match_operand:QI 0 "nonimmediate_operand" "g"))]
""
"tstb %0")
(define_insn "tstdf"
[(set (cc0)
(match_operand:DF 0 "general_operand" "gF"))]
""
"tst%# %0")
(define_insn "tstsf"
[(set (cc0)
(match_operand:SF 0 "general_operand" "gF"))]
""
"tstf %0")
(define_insn "cmpsi"
[(set (cc0)
(compare (match_operand:SI 0 "nonimmediate_operand" "g")
(match_operand:SI 1 "general_operand" "g")))]
""
"cmpl %0,%1")
(define_insn "cmphi"
[(set (cc0)
(compare (match_operand:HI 0 "nonimmediate_operand" "g")
(match_operand:HI 1 "general_operand" "g")))]
""
"cmpw %0,%1")
(define_insn "cmpqi"
[(set (cc0)
(compare (match_operand:QI 0 "nonimmediate_operand" "g")
(match_operand:QI 1 "general_operand" "g")))]
""
"cmpb %0,%1")
(define_insn "cmpdf"
[(set (cc0)
(compare (match_operand:DF 0 "general_operand" "gF,gF")
(match_operand:DF 1 "general_operand" "G,gF")))]
""
"@
tst%# %0
cmp%# %0,%1")
(define_insn "cmpsf"
[(set (cc0)
(compare (match_operand:SF 0 "general_operand" "gF,gF")
(match_operand:SF 1 "general_operand" "G,gF")))]
""
"@
tstf %0
cmpf %0,%1")
(define_insn ""
[(set (cc0)
(and:SI (match_operand:SI 0 "general_operand" "g")
(match_operand:SI 1 "general_operand" "g")))]
""
"bitl %0,%1")
(define_insn ""
[(set (cc0)
(and:HI (match_operand:HI 0 "general_operand" "g")
(match_operand:HI 1 "general_operand" "g")))]
""
"bitw %0,%1")
(define_insn ""
[(set (cc0)
(and:QI (match_operand:QI 0 "general_operand" "g")
(match_operand:QI 1 "general_operand" "g")))]
""
"bitb %0,%1")
;; The vax has no sltu or sgeu patterns, but does have two-operand
;; add/subtract with carry. This is still better than the alternative.
;; Since the cc0-using insn cannot be separated from the cc0-setting insn,
;; and the two are created independently, we can't just use a define_expand
;; to try to optimize this. (The "movl" and "clrl" insns alter the cc0
;; flags, but leave the carry flag alone, but that can't easily be expressed.)
;;
;; Several two-operator combinations could be added to make slightly more
;; optimal code, but they'd have to cover all combinations of plus and minus
;; using match_dup. If you want to do this, I'd suggest changing the "sgeu"
;; pattern to something like (minus (const_int 1) (ltu ...)), so fewer
;; patterns need to be recognized.
;; -- Ken Raeburn (Raeburn@Watch.COM) 24 August 1991.
(define_insn "sltu"
[(set (match_operand:SI 0 "general_operand" "=ro")
(ltu (cc0) (const_int 0)))]
""
"clrl %0\;adwc $0,%0")
(define_insn "sgeu"
[(set (match_operand:SI 0 "general_operand" "=ro")
(geu (cc0) (const_int 0)))]
""
"movl $1,%0\;sbwc $0,%0")
(define_insn "movdf"
[(set (match_operand:DF 0 "general_operand" "=g,g")
(match_operand:DF 1 "general_operand" "G,gF"))]
""
"@
clr%# %0
mov%# %1,%0")
(define_insn "movsf"
[(set (match_operand:SF 0 "general_operand" "=g,g")
(match_operand:SF 1 "general_operand" "G,gF"))]
""
"@
clrf %0
movf %1,%0")
;; Some vaxes don't support this instruction.
;;(define_insn "movti"
;; [(set (match_operand:TI 0 "general_operand" "=g")
;; (match_operand:TI 1 "general_operand" "g"))]
;; ""
;; "movh %1,%0")
(define_insn "movdi"
[(set (match_operand:DI 0 "general_operand" "=g,g")
(match_operand:DI 1 "general_operand" "I,g"))]
""
"@
clrq %0
movq %D1,%0")
;; The VAX move instructions have space-time tradeoffs. On a microVAX
;; register-register mov instructions take 3 bytes and 2 CPU cycles. clrl
;; takes 2 bytes and 3 cycles. mov from constant to register takes 2 cycles
;; if the constant is smaller than 4 bytes, 3 cycles for a longword
;; constant. movz, mneg, and mcom are as fast as mov, so movzwl is faster
;; than movl for positive constants that fit in 16 bits but not 6 bits. cvt
;; instructions take 4 cycles. inc takes 3 cycles. The machine description
;; is willing to trade 1 byte for 1 cycle (clrl instead of movl $0; cvtwl
;; instead of movl).
;; Cycle counts for other models may vary (on a VAX 750 they are similar,
;; but on a VAX 9000 most move and add instructions with one constant
;; operand take 1 cycle).
;; Loads of constants between 64 and 128 used to be done with
;; "addl3 $63,#,dst" but this is slower than movzbl and takes as much space.
(define_insn "movsi"
[(set (match_operand:SI 0 "general_operand" "=g")
(match_operand:SI 1 "general_operand" "g"))]
""
"*
{
rtx link;
if (operands[1] == const1_rtx
&& (link = find_reg_note (insn, REG_WAS_0, 0))
/* Make sure the insn that stored the 0 is still present. */
&& ! INSN_DELETED_P (XEXP (link, 0))
&& GET_CODE (XEXP (link, 0)) != NOTE
/* Make sure cross jumping didn't happen here. */
&& no_labels_between_p (XEXP (link, 0), insn))
return \"incl %0\";
if (GET_CODE (operands[1]) == SYMBOL_REF || GET_CODE (operands[1]) == CONST)
{
if (push_operand (operands[0], SImode))
return \"pushab %a1\";
return \"movab %a1,%0\";
}
if (operands[1] == const0_rtx)
return \"clrl %0\";
if (GET_CODE (operands[1]) == CONST_INT
&& (unsigned) INTVAL (operands[1]) >= 64)
{
int i = INTVAL (operands[1]);
if ((unsigned)(~i) < 64)
return \"mcoml %N1,%0\";
if ((unsigned)i < 0x100)
return \"movzbl %1,%0\";
if (i >= -0x80 && i < 0)
return \"cvtbl %1,%0\";
if ((unsigned)i < 0x10000)
return \"movzwl %1,%0\";
if (i >= -0x8000 && i < 0)
return \"cvtwl %1,%0\";
}
if (push_operand (operands[0], SImode))
return \"pushl %1\";
return \"movl %1,%0\";
}")
(define_insn "movhi"
[(set (match_operand:HI 0 "general_operand" "=g")
(match_operand:HI 1 "general_operand" "g"))]
""
"*
{
rtx link;
if (operands[1] == const1_rtx
&& (link = find_reg_note (insn, REG_WAS_0, 0))
/* Make sure the insn that stored the 0 is still present. */
&& ! INSN_DELETED_P (XEXP (link, 0))
&& GET_CODE (XEXP (link, 0)) != NOTE
/* Make sure cross jumping didn't happen here. */
&& no_labels_between_p (XEXP (link, 0), insn))
return \"incw %0\";
if (GET_CODE (operands[1]) == CONST_INT)
{
int i = INTVAL (operands[1]);
if (i == 0)
return \"clrw %0\";
else if ((unsigned int)i < 64)
return \"movw %1,%0\";
else if ((unsigned int)~i < 64)
return \"mcomw %H1,%0\";
else if ((unsigned int)i < 256)
return \"movzbw %1,%0\";
}
return \"movw %1,%0\";
}")
(define_insn "movstricthi"
[(set (strict_low_part (match_operand:HI 0 "register_operand" "=g"))
(match_operand:HI 1 "general_operand" "g"))]
""
"*
{
if (GET_CODE (operands[1]) =