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
/
tahoe.md
< prev
next >
Wrap
Text File
|
1994-02-06
|
55KB
|
2,157 lines
;;- Machine description for GNU compiler
;;- Tahoe version
;; Copyright (C) 1989 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.
; File: tahoe.md
;
; Original port made at the University of Buffalo by Devon Bowen,
; Dale Wiles and Kevin Zachmann.
;
; Piet van Oostrum (piet@cs.ruu.nl) made changes for HCX/UX, fixed
; some bugs and made some improvements (hopefully).
;
; Mail bugs reports or fixes to: gcc@cs.buffalo.edu
; movdi must call the output_move_double routine to move it around since
; the tahoe doesn't efficiently support 8 bit moves.
(define_insn "movdi"
[(set (match_operand:DI 0 "general_operand" "=g")
(match_operand:DI 1 "general_operand" "g"))]
""
"*
{
CC_STATUS_INIT;
return output_move_double (operands);
}")
; the trick in the movsi is accessing the contents of the sp register. The
; tahoe doesn't allow you to access it directly so you have to access the
; address of the top of the stack instead.
(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))
&& ! XEXP (link, 0)->volatil
&& GET_CODE (XEXP (link, 0)) != NOTE
&& 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 (push_operand (operands[0], SImode))
return \"pushl %1\";
if (GET_CODE(operands[1]) == REG && REGNO(operands[1]) == 14)
return \"moval (sp),%0\";
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))
&& ! XEXP (link, 0)->volatil
&& GET_CODE (XEXP (link, 0)) != NOTE
&& no_labels_between_p (XEXP (link, 0), insn))
return \"incw %0\";
if (operands[1] == const0_rtx)
return \"clrw %0\";
return \"movw %1,%0\";
}")
(define_insn "movqi"
[(set (match_operand:QI 0 "general_operand" "=g")
(match_operand:QI 1 "general_operand" "g"))]
""
"*
{
if (operands[1] == const0_rtx)
return \"clrb %0\";
return \"movb %1,%0\";
}")
; movsf has three cases since they can move from one place to another
; or to/from the fpp and since different instructions are needed for
; each case. The fpp related instructions don't set the flags properly.
(define_insn "movsf"
[(set (match_operand:SF 0 "general_operand" "=g,=a,=g")
(match_operand:SF 1 "general_operand" "g,g,a"))]
""
"*
{
CC_STATUS_INIT;
switch (which_alternative)
{
case 0: return \"movl %1,%0\";
case 1: return \"ldf %1\";
case 2: return \"stf %0\";
}
}")
; movdf has a number of different cases. If it's going to or from
; the fpp, use the special instructions to do it. If not, use the
; output_move_double function.
(define_insn "movdf"
[(set (match_operand:DF 0 "general_operand" "=a,=g,?=g")
(match_operand:DF 1 "general_operand" "g,a,g"))]
""
"*
{
CC_STATUS_INIT;
switch (which_alternative)
{
case 0:
return \"ldd %1\";
case 1:
if (push_operand (operands[0], DFmode))
return \"pushd\";
else
return \"std %0\";
case 2:
return output_move_double (operands);
}
}")
;========================================================================
; The tahoe has the following semantics for byte (and similar for word)
; operands: if the operand is a register or immediate, it takes the full 32
; bit operand, if the operand is memory, it sign-extends the byte. The
; operation is performed on the 32 bit values. If the destination is a
; register, the full 32 bit result is stored, if the destination is memory,
; of course only the low part is stored. The condition code is based on the
; 32 bit operation. Only on the movz instructions the byte from memory is
; zero-extended rather than sign-extended.
; This means that for arithmetic instructions we can use addb etc. to
; perform a long add from a signed byte from memory to a register. Of
; course this would also work for logical operations, but that doesn't seem
; very useful.
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (sign_extend:SI (match_operand:QI 1 "memory_operand" "m"))
(sign_extend:SI (match_operand:QI 2 "memory_operand" "m"))))]
""
"addb3 %1,%2,%0")
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (match_operand:SI 1 "nonmemory_operand" "%ri")
(sign_extend:SI (match_operand:QI 2 "memory_operand" "m"))))]
""
"*
{
if (rtx_equal_p (operands[0], operands[1]))
return \"addb2 %2,%0\";
return \"addb3 %1,%2,%0\";
}")
; We can also consider the result to be a half integer
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
(plus:HI (sign_extend:HI (match_operand:QI 1 "memory_operand" "m"))
(sign_extend:HI (match_operand:QI 2 "memory_operand" "m"))))]
""
"addb3 %1,%2,%0")
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
(plus:HI (match_operand:HI 1 "nonmemory_operand" "%ri")
(sign_extend:HI (match_operand:QI 2 "memory_operand" "m"))))]
""
"*
{
if (rtx_equal_p (operands[0], operands[1]))
return \"addb2 %2,%0\";
return \"addb3 %1,%2,%0\";
}")
; The same applies to words (HI)
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (sign_extend:SI (match_operand:HI 1 "memory_operand" "m"))
(sign_extend:SI (match_operand:HI 2 "memory_operand" "m"))))]
""
"addw3 %1,%2,%0")
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (match_operand:SI 1 "nonmemory_operand" "%ri")
(sign_extend:SI (match_operand:HI 2 "memory_operand" "m"))))]
""
"*
{
if (rtx_equal_p (operands[0], operands[1]))
return \"addw2 %2,%0\";
return \"addw3 %1,%2,%0\";
}")
; ======================= Now for subtract ==============================
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(minus:SI (sign_extend:SI (match_operand:QI 1 "memory_operand" "m"))
(sign_extend:SI (match_operand:QI 2 "memory_operand" "m"))))]
""
"subb3 %2,%1,%0")
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(minus:SI (match_operand:SI 1 "nonmemory_operand" "ri")
(sign_extend:SI (match_operand:QI 2 "memory_operand" "m"))))]
""
"*
{
if (rtx_equal_p (operands[0], operands[1]))
return \"subb2 %2,%0\";
return \"subb3 %2,%1,%0\";
}")
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(minus:SI (sign_extend:SI (match_operand:QI 1 "memory_operand" "m"))
(match_operand:SI 2 "nonmemory_operand" "ri")))]
""
"subb3 %2,%1,%0")
; We can also consider the result to be a half integer
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
(minus:HI (sign_extend:HI (match_operand:QI 1 "memory_operand" "m"))
(sign_extend:HI (match_operand:QI 2 "memory_operand" "m"))))]
""
"subb3 %2,%1,%0")
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
(minus:HI (match_operand:HI 1 "nonmemory_operand" "%ri")
(sign_extend:HI (match_operand:QI 2 "memory_operand" "m"))))]
""
"*
{
if (rtx_equal_p (operands[0], o