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
/
arm.md
< prev
next >
Wrap
Text File
|
1994-02-06
|
37KB
|
1,318 lines
;;- Machine description Acorn RISC Machine for GNU compiler
;; Copyright (C) 1991 Free Software Foundation, Inc.
;; Contributed by Pieter `Tiggr' Schoenmakers (rcpieter@win.tue.nl)
;; and Martin Simmons (@harleqn.co.uk).
;; 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.
;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
;; Every template must be output by arm_output_asm_insn, since this keeps
;; track of the offset of labels within the text segment. This is needed to
;; to be able to (correctly) output instructions for loading a value from a
;; function's constant pool, since different instructions are needed when the
;; constant pool is more than 4095 bytes away from the PC.
;; Addition insns.
(define_insn "adddi3"
[(set (match_operand:DI 0 "di_operand" "=&r")
(plus:DI (match_operand:DI 1 "di_operand" "%r")
(match_operand:DI 2 "di_operand" "r")))]
""
"*
arm_output_asm_insn (\"adds\\t%0, %1, %2\", operands);
return (arm_output_asm_insn (\"adc\\t%R0, %R1, %R2\", operands));
")
(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 "general_operand" "r,n")))]
""
"*
switch (which_alternative)
{
case 0:
return (arm_output_asm_insn (\"add\\t%0, %1, %2\", operands));
case 1:
return (output_add_immediate (operands));
}
")
(define_insn "addsf3"
[(set (match_operand:SF 0 "register_operand" "=f")
(plus:SF (match_operand:SF 1 "register_operand" "f")
(match_operand:SF 2 "fpu_rhs_operand" "fG")))]
""
"*
return (arm_output_asm_insn (\"adfs\\t%0, %1, %2\", operands));
")
(define_insn "adddf3"
[(set (match_operand:DF 0 "register_operand" "=f")
(plus:DF (match_operand:DF 1 "register_operand" "f")
(match_operand:DF 2 "fpu_rhs_operand" "fG")))]
""
"*
return (arm_output_asm_insn (\"adfd\\t%0, %1, %2\", operands));
")
(define_insn "subdi3"
[(set (match_operand:DI 0 "di_operand" "=&r")
(minus:DI (match_operand:DI 1 "di_operand" "%r")
(match_operand:DI 2 "di_operand" "r")))]
""
"*
arm_output_asm_insn (\"subs\\t%0, %1, %2\", operands);
return (arm_output_asm_insn (\"sbc\\t%R0, %R1, %R2\", operands));
")
(define_insn "subsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
(minus:SI (match_operand:SI 1 "arm_rhs_operand" "r,r,I")
(match_operand:SI 2 "general_operand" "r,n,r")))]
""
"*
switch (which_alternative)
{
case 0:
return (arm_output_asm_insn (\"sub\\t%0, %1, %2\", operands));
case 1:
operands[2] = gen_rtx (CONST_INT, VOIDmode, -INTVAL (operands[2]));
return (output_add_immediate (operands));
case 2:
return (arm_output_asm_insn (\"rsb\\t%0, %2, %1\", operands));
}
")
(define_insn "subsf3"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(minus:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
(match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
""
"*
switch (which_alternative)
{
case 0:
return (arm_output_asm_insn (\"sufs\\t%0, %1, %2\", operands));
case 1:
return (arm_output_asm_insn (\"rsfs\\t%0, %2, %1\", operands));
}
")
(define_insn "subdf3"
[(set (match_operand:DF 0 "register_operand" "=f,f")
(minus:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
(match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
""
"*
switch (which_alternative)
{
case 0:
return (arm_output_asm_insn (\"sufd\\t%0, %1, %2\", operands));
case 2:
return (arm_output_asm_insn (\"rsfd\\t%0, %2, %1\", operands));
}
")
;; Multiplication insns
;; The `&' is too strict, but at least generates correct code.
(define_insn "mulsi3"
[(set (match_operand:SI 0 "register_operand" "=&r")
(mult:SI (match_operand:SI 1 "register_operand" "%r")
(match_operand:SI 2 "register_operand" "r")))]
""
"*
if (REGNO (operands[0]) == REGNO (operands[1]))
return (arm_output_asm_insn (\"mul\\t%0, %2, %1\", operands));
else
return (arm_output_asm_insn (\"mul\\t%0, %1, %2\", operands));
")
;; Unnamed templates to match MLA instruction.
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=&r")
(plus:SI
(mult:SI (match_operand:SI 1 "register_operand" "%r")
(match_operand:SI 2 "register_operand" "r"))
(match_operand:SI 3 "register_operand" "r")))]
""
"*
if (REGNO (operands[0]) == REGNO (operands[1]))
return (arm_output_asm_insn (\"mla\\t%0, %2, %1, %3\", operands));
else
return (arm_output_asm_insn (\"mla\\t%0, %1, %2, %3\", operands));
")
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=&r")
(plus:SI
(match_operand:SI 3 "register_operand" "r")
(mult:SI (match_operand:SI 1 "register_operand" "%r")
(match_operand:SI 2 "register_operand" "r"))))]
""
"*
if (REGNO (operands[0]) == REGNO (operands[1]))
return (arm_output_asm_insn (\"mla\\t%0, %2, %1, %3\", operands));
else
return (arm_output_asm_insn (\"mla\\t%0, %1, %2, %3\", operands));
")
(define_insn "mulsf3"
[(set (match_operand:SF 0 "register_operand" "=f")
(mult:SF (match_operand:SF 1 "register_operand" "f")
(match_operand:SF 2 "fpu_rhs_operand" "fG")))]
""
"*return (arm_output_asm_insn (\"mufs\\t%0, %1, %2\", operands));")
(define_insn "muldf3"
[(set (match_operand:DF 0 "register_operand" "=f")
(mult:DF (match_operand:DF 1 "register_operand" "f")
(match_operand:DF 2 "fpu_rhs_operand" "fG")))]
""
"*
return (arm_output_asm_insn (\"mufd\\t%0, %1, %2\", operands));
")
;; Division insns
(define_insn "divsf3"
[(set (match_operand:SF 0 "register_operand" "=f,f")
(div:SF (match_operand:SF 1 "fpu_rhs_operand" "f,G")
(match_operand:SF 2 "fpu_rhs_operand" "fG,f")))]
""
"*
switch (which_alternative)
{
case 0:
return (arm_output_asm_insn (\"dvfs\\t%0, %1, %2\", operands));
case 1:
return (arm_output_asm_insn (\"rdfs\\t%0, %2, %1\", operands));
}
")
(define_insn "divdf3"
[(set (match_operand:DF 0 "register_operand" "=f,f")
(div:DF (match_operand:DF 1 "fpu_rhs_operand" "f,G")
(match_operand:DF 2 "fpu_rhs_operand" "fG,f")))]
""
"*
switch (which_alternative)
{
case 0:
return (arm_output_asm_insn (\"dvfd\\t%0, %1, %2\", operands));
case 1:
return (arm_output_asm_insn (\"rdfd\\t%0, %2, %1\", operands));
}
")
;; Modulo insns
(define_insn "modsf3"
[(set (match_operand:SF 0 "register_operand" "=f")
(mod:SF (match_operand:SF 1 "register_operand" "f")
(match_operand:SF 2 "fpu_rhs_operand" "fG")))]
""
"*
return (arm_output_asm_insn (\"rmfs\\t%0, %1, %2\", operands));
")
(define_insn "moddf3"
[(set (match_operand:DF 0 "register_operand" "=f")
(mod:DF (match_operand:DF 1 "register_operand" "f")
(match_operand:DF 2 "fpu_rhs_operand" "fG")))]
""
"*
return (arm_output_asm_insn (\"rmfd\\t%0, %1, %2\", operands));
")
;; Boolean and,ior,xor insns
(define_insn "anddi3"
[(set (match_operand:DI 0 "di_operand" "=&r")
(and:DI (match_operand:DI 1 "di_operand" "%r")
(match_operand:DI 2 "di_operand" "r")))]
""
"*
arm_output_asm_insn (\"and\\t%0, %1, %2\", operands);
return (arm_output_asm_insn (\"and\\t%R0, %R1, %R2\", operands));
")
(define_insn "andsi3"
[(set (match_operand:SI 0 "register_operand" "=r")
(and:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "arm_rhs_operand" "rI")))]
""
"*
return (arm_output_asm_insn (\"and\\t%0, %1, %2\", operands));
")
(define_insn "andcbsi3"
[(set (match_operand:SI