diff options
author | kenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4> | 1992-01-08 11:12:04 +0000 |
---|---|---|
committer | kenner <kenner@138bc75d-0d04-0410-961f-82ee72b054a4> | 1992-01-08 11:12:04 +0000 |
commit | 10bc45a5aa72d1c0144ec290ec91b64708f52bb0 (patch) | |
tree | b2a32b91c9071065fd0ff8dfeef04b21ada76c60 /gcc/config/convex/convex.md | |
parent | ea3a6df6a9c21919cd465111df6710a2eede3581 (diff) | |
download | gcc-10bc45a5aa72d1c0144ec290ec91b64708f52bb0.tar.gz |
Initial revision
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@173 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/config/convex/convex.md')
-rw-r--r-- | gcc/config/convex/convex.md | 1334 |
1 files changed, 1334 insertions, 0 deletions
diff --git a/gcc/config/convex/convex.md b/gcc/config/convex/convex.md new file mode 100644 index 00000000000..4e7ea5a99f0 --- /dev/null +++ b/gcc/config/convex/convex.md @@ -0,0 +1,1334 @@ +;;- Machine description for GNU compiler +;;- Convex Version +;; Copyright (C) 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. + +;; Scheduling defs +;; +;; Insn scheduling is not used at present. Scheduling increases +;; register pressure so much that many spills are generated +;; even for very small functions. + +;; Compares + +(define_insn "tstsi" + [(set (cc0) + (match_operand:SI 0 "register_operand" "r"))] + "" + "* return set_cmp (operands[0], const0_rtx, 'w');") + +(define_insn "tsthi" + [(set (cc0) + (match_operand:HI 0 "register_operand" "r"))] + "" + "* return set_cmp (operands[0], const0_rtx, 'h');") + +(define_expand "tstqi" + [(set (match_dup 1) + (sign_extend:SI (match_operand:QI 0 "register_operand" "r"))) + (set (cc0) + (match_dup 1))] + "" + "operands[1] = gen_reg_rtx (SImode);") + +(define_expand "tstdi" + [(parallel [(set (cc0) (match_operand:DI 0 "register_operand" "d")) + (use (match_dup 1))])] + "" + "operands[1] = force_reg (DImode, const0_rtx);") + +(define_insn "" + [(set (cc0) (match_operand:DI 0 "register_operand" "d")) + (use (match_operand:DI 1 "register_operand" "d"))] + "" + "* return set_cmp (operands[0], operands[1], 'l');") + +(define_expand "tstdf" + [(set (cc0) + (compare (match_operand:DF 0 "register_operand" "d") + (match_dup 1)))] + "" + "operands[1] = force_reg (DFmode, CONST0_RTX (DFmode));") + +(define_insn "tstsf" + [(set (cc0) + (match_operand:SF 0 "register_operand" "d"))] + "" + "* return set_cmp (operands[0], CONST0_RTX (SFmode), 's');") + +(define_insn "cmpsi" + [(set (cc0) + (compare (match_operand:SI 0 "register_operand" "d,a,i,r") + (match_operand:SI 1 "nonmemory_operand" "d,a,r,i")))] + "" + "* return set_cmp (operands[0], operands[1], 'w');") + +(define_insn "cmphi" + [(set (cc0) + (compare (match_operand:HI 0 "register_operand" "d,a,r,i") + (match_operand:HI 1 "nonmemory_operand" "d,a,i,r")))] + "" + "* return set_cmp (operands[0], operands[1], 'h');") + +(define_insn "cmpqi" + [(set (cc0) + (compare (match_operand:QI 0 "register_operand" "d") + (match_operand:QI 1 "register_operand" "d")))] + "" + "* return set_cmp (operands[0], operands[1], 'b');") + +(define_insn "cmpdi" + [(set (cc0) + (compare (match_operand:DI 0 "register_operand" "d") + (match_operand:DI 1 "register_operand" "d")))] + "" + "* return set_cmp (operands[0], operands[1], 'l');") + +(define_insn "cmpdf" + [(set (cc0) + (compare (match_operand:DF 0 "register_operand" "d") + (match_operand:DF 1 "register_operand" "d")))] + "" + "* return set_cmp (operands[0], operands[1], 'd');") + +(define_insn "cmpsf" + [(set (cc0) + (compare (match_operand:SF 0 "nonmemory_operand" "dF,d") + (match_operand:SF 1 "nonmemory_operand" "d,F")))] + "" + "* return set_cmp (operands[0], operands[1], 's');") + +;; Moves + +;(define_insn "movtf" +; [(set (match_operand:TF 0 "general_operand" "=g,d") +; (match_operand:TF 1 "general_operand" "d,g"))] +; "" +; "* +;{ +; rtx opaddr = 0; +; rtx xoperands[4]; +; xoperands[0] = operands[0]; +; xoperands[2] = operands[1]; +; +; if (REG_P (operands[0])) +; xoperands[1] = gen_rtx (REG, TFmode, REGNO (operands[0]) + 1); +; else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC) +; xoperands[1] = 0; +; else if (offsettable_memref_p (operands[0])) +; xoperands[1] = adj_offsettable_operand (operands[0], 8); +; else +; { +; opaddr = XEXP (operands[0], 0); +; xoperands[0] = gen_rtx (MEM, TFmode, gen_rtx (REG, SImode, 13)); +; xoperands[1] = adj_offsettable_operand (xoperands[0], 8); +; } +; +; if (REG_P (operands[1])) +; xoperands[3] = gen_rtx (REG, TFmode, REGNO (operands[1]) + 1); +; else if (offsettable_memref_p (operands[1])) +; xoperands[3] = adj_offsettable_operand (operands[1], 8); +; else +; { +; opaddr = XEXP (operands[1], 0); +; xoperands[2] = gen_rtx (MEM, TFmode, gen_rtx (REG, SImode, 13)); +; xoperands[3] = adj_offsettable_operand (xoperands[2], 8); +; } +; +; if (opaddr) +; output_asm_insn (\"psh.w a5\;ld.w %0,a5\", &opaddr); +; if (push_operand (operands[0], TFmode)) +; output_asm_insn (\"psh.l %3\;psh.l %2\", xoperands); +; else if (GET_CODE (operands[0]) == MEM) +; output_asm_insn (\"st.l %2,%0\;st.l %3,%1\", xoperands); +; else if (GET_CODE (operands[1]) == REG) +; output_asm_insn (\"mov %2,%0\;mov %3,%1\", xoperands); +; else +; output_asm_insn (\"ld.l %2,%0\;ld.l %3,%1\", xoperands); +; if (opaddr) +; output_asm_insn (\"pop.w a5\"); +; return \"\"; +;}") + +(define_insn "movdf" + [(set (match_operand:DF 0 "general_operand" "=g,d") + (match_operand:DF 1 "general_operand" "d,dmG"))] + "" + "* +{ + if (push_operand (operands[0], DFmode)) + return \"psh.l %1\"; + else if (GET_CODE (operands[0]) == MEM) + return \"st.l %1,%0\"; + else if (GET_CODE (operands[1]) == REG) + return \"mov %1,%0\"; + else if (GET_CODE (operands[1]) == CONST_DOUBLE && LD_D_P (operands[1])) + { + operands[1] = gen_rtx (CONST_INT, VOIDmode, + const_double_high_int (operands[1])); + return \"ld.d %1,%0\"; + } + else if (GET_CODE (operands[1]) == CONST_DOUBLE && LD_L_P (operands[1])) + { + operands[1] = gen_rtx (CONST_INT, VOIDmode, + const_double_low_int (operands[1])); + return \"ld.l %1,%0\"; + } + else + return \"ld.l %1,%0\"; +}") + +(define_insn "movsf" + [(set (match_operand:SF 0 "general_operand" "=g,d") + (match_operand:SF 1 "general_operand" "d,gF"))] + "" + "* +{ + if (push_operand (operands[0], SFmode)) + return \"psh.w %1\"; + else if (GET_CODE (operands[0]) == MEM) + return \"st.s %1,%0\"; + else if (GET_CODE (operands[1]) == REG) + return \"mov.s %1,%0\"; + else + return \"ld.s %1,%0\"; +}") + +(define_insn "movdi" + [(set (match_operand:DI 0 "general_operand" "=g,d") + (match_operand:DI 1 "general_operand" "d,dmiG"))] + "" + "* +{ + if (push_operand (operands[0], DImode)) + return \"psh.l %1\"; + else if (GET_CODE (operands[0]) == MEM) + return \"st.l %1,%0\"; + else if (GET_CODE (operands[1]) == REG) + return \"mov %1,%0\"; + else if (GET_CODE (operands[1]) == CONST_DOUBLE && LD_D_P (operands[1])) + { + operands[1] = gen_rtx (CONST_INT, VOIDmode, + const_double_high_int (operands[1])); + return \"ld.d %1,%0\"; + } + else + return \"ld.l %1,%0\"; +}") + +;; Special case of movsi, needed to express A-reg preference. + +(define_insn "" + [(set (match_operand:SI 0 "push_operand" "=<") + (plus:SI (match_operand:SI 1 "register_operand" "a") + (match_operand:SI 2 "immediate_operand" "i")))] + "operands[1] != stack_pointer_rtx" + "pshea %a2(%1)") + +;; General movsi. Constraints will be selected based on TARGET_INDIRECTS +;; to avoid indirect addressing on C3, where it is slow. + +(define_expand "movsi" + [(set (match_operand:SI 0 "general_operand" "") + (match_operand:SI 1 "general_operand" ""))] + "" + "") + +(define_insn "" + [(set (match_operand:SI 0 "general_operand" "=g,r,<") + (match_operand:SI 1 "general_operand" "r,g,io"))] + "TARGET_INDIRECTS" + "* +{ + if (push_operand (operands[0], SImode)) + { + if (GET_CODE (operands[1]) == REG) + return \"psh.w %1\"; + else + return \"pshea %a1\"; + } + if (GET_CODE (operands[0]) == MEM) + return \"st.w %1,%0\"; + if (GET_CODE (operands[1]) != REG) + return \"ld.w %1,%0\"; + if (S_REG_P (operands[0]) && S_REG_P (operands[1])) + return \"mov.w %1,%0\"; + return \"mov %1,%0\"; +}") + +(define_insn "" + [(set (match_operand:SI 0 "general_operand" "=g,r,<") + (match_operand:SI 1 "general_operand" "r,g,i"))] + "! TARGET_INDIRECTS" + "* +{ + if (push_operand (operands[0], SImode)) + { + if (GET_CODE (operands[1]) == REG) + return \"psh.w %1\"; + else + return \"pshea %a1\"; + } + if (GET_CODE (operands[0]) == MEM) + return \"st.w %1,%0\"; + if (GET_CODE (operands[1]) != REG) + return \"ld.w %1,%0\"; + if (S_REG_P (operands[0]) && S_REG_P (operands[1])) + return \"mov.w %1,%0\"; + return \"mov %1,%0\"; +}") + +(define_insn "movstrictsi" + [(set (strict_low_part (match_operand:SI 0 "general_operand" "=g,r")) + (match_operand:SI 1 "general_operand" "r,g"))] + "" + "* +{ + if (GET_CODE (operands[0]) == MEM) + return \"st.w %1,%0\"; + if (GET_CODE (operands[1]) != REG) + return \"ld.w %1,%0\"; + if (S_REG_P (operands[0]) && S_REG_P (operands[1])) + return \"mov.w %1,%0\"; + return \"mov %1,%0\"; +}") + +(define_insn "movhi" + [(set (match_operand:HI 0 "general_operand" "=g,r") + (match_operand:HI 1 "general_operand" "r,g"))] + "" + "* +{ + if (push_operand (operands[0], HImode)) + abort (); + else if (GET_CODE (operands[0]) == MEM) + return \"st.h %1,%0\"; + else if (GET_CODE (operands[1]) == REG) + { + if (S_REG_P (operands[0]) && S_REG_P (operands[1])) + return \"mov.w %1,%0\"; + else + return \"mov %1,%0\"; + } + else if (GET_CODE (operands[1]) == CONST_INT) + return \"ld.w %1,%0\"; + else + return \"ld.h %1,%0\"; +}") + +(define_insn "movqi" + [(set (match_operand:QI 0 "general_operand" "=g,r") + (match_operand:QI 1 "general_operand" "r,g"))] + "" + "* +{ + if (push_operand (operands[0], QImode)) + abort (); + else if (GET_CODE (operands[0]) == MEM) + return \"st.b %1,%0\"; + else if (GET_CODE (operands[1]) == REG) + { + if (S_REG_P (operands[0]) && S_REG_P (operands[1])) + return \"mov.w %1,%0\"; + else + return \"mov %1,%0\"; + } + else if (GET_CODE (operands[1]) == CONST_INT) + return \"ld.w %1,%0\"; + else + return \"ld.b %1,%0\"; +}") + +;; Extension and truncation insns. +;; Those for integer source operand +;; are ordered widest source type first. + +(define_insn "truncsiqi2" + [(set (match_operand:QI 0 "register_operand" "=d,a") + (truncate:QI (match_operand:SI 1 "register_operand" "d,a")))] + "" + "cvtw.b %1,%0") + +(define_insn "truncsihi2" + [(set (match_operand:HI 0 "register_operand" "=d,a") + (truncate:HI (match_operand:SI 1 "register_operand" "d,a")))] + "" + "cvtw.h %1,%0") + +(define_insn "trunchiqi2" + [(set (match_operand:QI 0 "register_operand" "=r") + (truncate:QI (match_operand:HI 1 "register_operand" "0")))] + "" + "") + +(define_insn "truncdisi2" + [(set (match_operand:SI 0 "register_operand" "=d") + (truncate:SI (match_operand:DI 1 "register_operand" "d")))] + "" + "cvtl.w %1,%0") + +(define_insn "extendsidi2" + [(set (match_operand:DI 0 "register_operand" "=d") + (sign_extend:DI (match_operand:SI 1 "register_operand" "d")))] + "" + "cvtw.l %1,%0") + +(define_insn "extendhisi2" + [(set (match_operand:SI 0 "register_operand" "=d,a") + (sign_extend:SI (match_operand:HI 1 "register_operand" "d,a")))] + "" + "cvth.w %1,%0") + +(define_insn "extendqihi2" + [(set (match_operand:HI 0 "register_operand" "=d,a") + (sign_extend:HI (match_operand:QI 1 "register_operand" "d,a")))] + "" + "cvtb.w %1,%0") + +(define_insn "extendqisi2" + [(set (match_operand:SI 0 "register_operand" "=d,a") + (sign_extend:SI (match_operand:QI 1 "register_operand" "d,a")))] + "" + "cvtb.w %1,%0") + +(define_insn "extendsfdf2" + [(set (match_operand:DF 0 "register_operand" "=d") + (float_extend:DF (match_operand:SF 1 "register_operand" "d")))] + "" + "cvts.d %1,%0") + +(define_insn "truncdfsf2" + [(set (match_operand:SF 0 "register_operand" "=d") + (float_truncate:SF (match_operand:DF 1 "register_operand" "d")))] + "" + "cvtd.s %1,%0") + +(define_insn "zero_extendhisi2" + [(set (match_operand:SI 0 "register_operand" "=r") + (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))] + "" + "and #0xffff,%0") + +(define_insn "zero_extendqihi2" + [(set (match_operand:HI 0 "register_operand" "=r") + (zero_extend:HI (match_operand:QI 1 "register_operand" "0")))] + "" + "and #0xff,%0") + +(define_insn "zero_extendqisi2" + [(set (match_operand:SI 0 "register_operand" "=r") + (zero_extend:SI (match_operand:QI 1 "register_operand" "0")))] + "" + "and #0xff,%0") + +(define_insn "zero_extendsidi2" + [(set (match_operand:DI 0 "register_operand" "=d") + (zero_extend:DI (match_operand:SI 1 "register_operand" "0")))] + "" + "ld.u #0,%0") + +;; Fix-to-float conversion insns. +;; Note that 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. + +(define_insn "floatsisf2" + [(set (match_operand:SF 0 "register_operand" "=d") + (float:SF (match_operand:SI 1 "register_operand" "d")))] + "" + "cvtw.s %1,%0") + +(define_insn "floatdisf2" + [(set (match_operand:SF 0 "register_operand" "=d") + (float:SF (match_operand:DI 1 "register_operand" "d")))] + "" + "cvtl.s %1,%0") + +(define_insn "floatsidf2" + [(set (match_operand:DF 0 "register_operand" "=d") + (float:DF (match_operand:SI 1 "register_operand" "d")))] + "TARGET_C2" + "cvtw.d %1,%0") + +(define_insn "floatdidf2" + [(set (match_operand:DF 0 "register_operand" "=d") + (float:DF (match_operand:DI 1 "register_operand" "d")))] + "" + "cvtl.d %1,%0") + +;; Float-to-fix conversion insns. + +(define_insn "fix_truncsfsi2" + [(set (match_operand:SI 0 "register_operand" "=d") + (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "d"))))] + "" + "cvts.w %1,%0") + +(define_insn "fix_truncsfdi2" + [(set (match_operand:DI 0 "register_operand" "=d") + (fix:DI (fix:SF (match_operand:SF 1 "register_operand" "d"))))] + "" + "cvts.l %1,%0") + +(define_insn "fix_truncdfsi2" + [(set (match_operand:SI 0 "register_operand" "=d") + (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "d"))))] + "" + "* +{ + if (TARGET_C2) + return \"cvtd.w %1,%0\"; + return \"cvtd.l %1,%0\"; +}") + +(define_insn "fix_truncdfdi2" + [(set (match_operand:DI 0 "register_operand" "=d") + (fix:DI (fix:DF (match_operand:DF 1 "register_operand" "d"))))] + "" + "cvtd.l %1,%0") + +;;- All kinds of add instructions. + +(define_insn "adddf3" + [(set (match_operand:DF 0 "register_operand" "=d") + (plus:DF (match_operand:DF 1 "register_operand" "%0") + (match_operand:DF 2 "register_operand" "d")))] + "" + "add.d %2,%0") + +(define_insn "addsf3" + [(set (match_operand:SF 0 "register_operand" "=d") + (plus:SF (match_operand:SF 1 "register_operand" "%0") + (match_operand:SF 2 "nonmemory_operand" "dF")))] + "" + "add.s %2,%0") + +(define_insn "adddi3" + [(set (match_operand:DI 0 "register_operand" "=d") + (plus:DI (match_operand:DI 1 "register_operand" "%0") + (match_operand:DI 2 "register_operand" "d")))] + "" + "add.l %2,%0") + +;; special case of addsi3, needed to specify an A reg for the destination +;; when the source is a sum involving FP or AP. + +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=a") + (plus:SI (match_operand:SI 1 "register_operand" "%a") + (match_operand:SI 2 "immediate_operand" "i")))] + "operands[1] == frame_pointer_rtx || operands[1] == arg_pointer_rtx" + "ldea %a2(%1),%0") + +(define_insn "addsi3" + [(set (match_operand:SI 0 "register_operand" "=d,a,a") + (plus:SI (match_operand:SI 1 "nonmemory_operand" "%0,0,a") + (match_operand:SI 2 "nonmemory_operand" "di,ri,i")))] + "" + "* switch (which_alternative) +{ + case 0: + case 1: + return \"add.w %2,%0\"; + case 2: + if ((TARGET_C2 || A_REG_P (operands[0])) + && operands[1] != stack_pointer_rtx) + return \"ldea %a2(%1),%0\"; + else + return \"mov %1,%0\;add.w %2,%0\"; +}") + +(define_insn "addhi3" + [(set (match_operand:HI 0 "register_operand" "=d,a") + (plus:HI (match_operand:HI 1 "register_operand" "%0,0") + (match_operand:HI 2 "nonmemory_operand" "di,ai")))] + "" + "add.h %2,%0") + +(define_insn "addqi3" + [(set (match_operand:QI 0 "register_operand" "=d") + (plus:QI (match_operand:QI 1 "register_operand" "%0") + (match_operand:QI 2 "register_operand" "d")))] + "" + "add.b %2,%0") + +;;- All kinds of subtract instructions. + +(define_insn "subdf3" + [(set (match_operand:DF 0 "register_operand" "=d") + (minus:DF (match_operand:DF 1 "register_operand" "0") + (match_operand:DF 2 "register_operand" "d")))] + "" + "sub.d %2,%0") + +(define_insn "subsf3" + [(set (match_operand:SF 0 "register_operand" "=d") + (minus:SF (match_operand:SF 1 "register_operand" "0") + (match_operand:SF 2 "nonmemory_operand" "dF")))] + "" + "sub.s %2,%0") + +(define_insn "subdi3" + [(set (match_operand:DI 0 "register_operand" "=d") + (minus:DI (match_operand:DI 1 "register_operand" "0") + (match_operand:DI 2 "register_operand" "d")))] + "" + "sub.l %2,%0") + +(define_insn "subsi3" + [(set (match_operand:SI 0 "register_operand" "=d,a") + (minus:SI (match_operand:SI 1 "register_operand" "0,0") + (match_operand:SI 2 "nonmemory_operand" "di,ai")))] + "" + "sub.w %2,%0") + +(define_insn "subhi3" + [(set (match_operand:HI 0 "register_operand" "=d,a") + (minus:HI (match_operand:HI 1 "register_operand" "0,0") + (match_operand:HI 2 "nonmemory_operand" "di,ai")))] + "" + "sub.h %2,%0") + +(define_insn "subqi3" + [(set (match_operand:QI 0 "register_operand" "=d") + (minus:QI (match_operand:QI 1 "register_operand" "0") + (match_operand:QI 2 "register_operand" "d")))] + "" + "sub.b %2,%0") + +;;- Multiply instructions. + +(define_insn "muldf3" + [(set (match_operand:DF 0 "register_operand" "=d") + (mult:DF (match_operand:DF 1 "register_operand" "%0") + (match_operand:DF 2 "register_operand" "d")))] + "" + "mul.d %2,%0") + +(define_insn "mulsf3" + [(set (match_operand:SF 0 "register_operand" "=d") + (mult:SF (match_operand:SF 1 "register_operand" "%0") + (match_operand:SF 2 "nonmemory_operand" "dF")))] + "" + "mul.s %2,%0") + +(define_insn "muldi3" + [(set (match_operand:DI 0 "register_operand" "=d") + (mult:DI (match_operand:DI 1 "register_operand" "%0") + (match_operand:DI 2 "register_operand" "d")))] + "" + "mul.l %2,%0") + +(define_insn "mulsi3" + [(set (match_operand:SI 0 "register_operand" "=d,a") + (mult:SI (match_operand:SI 1 "register_operand" "%0,0") + (match_operand:SI 2 "nonmemory_operand" "di,ai")))] + "" + "mul.w %2,%0") + +(define_insn "mulhi3" + [(set (match_operand:HI 0 "register_operand" "=d,a") + (mult:HI (match_operand:HI 1 "register_operand" "%0,0") + (match_operand:HI 2 "nonmemory_operand" "di,ai")))] + "" + "mul.h %2,%0") + +(define_insn "mulqi3" + [(set (match_operand:QI 0 "register_operand" "=d") + (mult:QI (match_operand:QI 1 "register_operand" "%0") + (match_operand:QI 2 "register_operand" "d")))] + "" + "mul.b %2,%0") + +;;- Divide instructions. + +(define_insn "divdf3" + [(set (match_operand:DF 0 "register_operand" "=d") + (div:DF (match_operand:DF 1 "register_operand" "0") + (match_operand:DF 2 "register_operand" "d")))] + "" + "div.d %2,%0") + +(define_insn "divsf3" + [(set (match_operand:SF 0 "register_operand" "=d") + (div:SF (match_operand:SF 1 "register_operand" "0") + (match_operand:SF 2 "nonmemory_operand" "dF")))] + "" + "div.s %2,%0") + +(define_insn "divdi3" + [(set (match_operand:DI 0 "register_operand" "=d") + (div:DI (match_operand:DI 1 "register_operand" "0") + (match_operand:DI 2 "register_operand" "d")))] + "" + "div.l %2,%0") + +(define_insn "udivdi3" + [(set (match_operand:DI 0 "register_operand" "=d") + (udiv:DI (match_operand:DI 1 "register_operand" "d") + (match_operand:DI 2 "register_operand" "d")))] + "" + "psh.l %2\;psh.l %1\;callq udiv64\;pop.l %0\;add.w #8,sp") + +(define_insn "divsi3" + [(set (match_operand:SI 0 "register_operand" "=d,a") + (div:SI (match_operand:SI 1 "register_operand" "0,0") + (match_operand:SI 2 "nonmemory_operand" "di,ai")))] + "" + "div.w %2,%0") + +(define_insn "divhi3" + [(set (match_operand:HI 0 "register_operand" "=d,a") + (div:HI (match_operand:HI 1 "register_operand" "0,0") + (match_operand:HI 2 "nonmemory_operand" "di,ai")))] + "" + "div.h %2,%0") + +(define_insn "divqi3" + [(set (match_operand:QI 0 "register_operand" "=d") + (div:QI (match_operand:QI 1 "register_operand" "0") + (match_operand:QI 2 "register_operand" "d")))] + "" + "div.b %2,%0") + +;; - and, or, xor + +(define_insn "" + [(set (match_operand:DI 0 "register_operand" "=d") + (and:DI (match_operand:DI 1 "register_operand" "%0") + (match_operand:DI 2 "immediate_operand" "Fn")))] + "GET_CODE (operands[2]) == CONST_INT + || (GET_CODE (operands[2]) == CONST_DOUBLE + && CONST_DOUBLE_HIGH (operands[2]) == -1)" + "and %2,%0") + +(define_insn "anddi3" + [(set (match_operand:DI 0 "register_operand" "=d") + (and:DI (match_operand:DI 1 "register_operand" "%0") + (match_operand:DI 2 "register_operand" "d")))] + "" + "and %2,%0") + +(define_insn "andsi3" + [(set (match_operand:SI 0 "register_operand" "=d,a") + (and:SI (match_operand:SI 1 "register_operand" "%0,0") + (match_operand:SI 2 "nonmemory_operand" "di,ai")))] + "" + "and %2,%0") + +(define_insn "andhi3" + [(set (match_operand:HI 0 "register_operand" "=d,a") + (and:HI (match_operand:HI 1 "register_operand" "%0,0") + (match_operand:HI 2 "nonmemory_operand" "di,ai")))] + "" + "and %2,%0") + +(define_insn "andqi3" + [(set (match_operand:QI 0 "register_operand" "=d,a") + (and:QI (match_operand:QI 1 "register_operand" "%0,0") + (match_operand:QI 2 "nonmemory_operand" "di,ai")))] + "" + "and %2,%0") + +;;- Bit set instructions. + +(define_insn "" + [(set (match_operand:DI 0 "register_operand" "=d") + (ior:DI (match_operand:DI 1 "register_operand" "%0") + (match_operand:DI 2 "immediate_operand" "Fn")))] + "GET_CODE (operands[2]) == CONST_INT + || (GET_CODE (operands[2]) == CONST_DOUBLE + && CONST_DOUBLE_HIGH (operands[2]) == 0)" + "or %2,%0") + +(define_insn "iordi3" + [(set (match_operand:DI 0 "register_operand" "=d") + (ior:DI (match_operand:DI 1 "register_operand" "%0") + (match_operand:DI 2 "register_operand" "d")))] + "" + "or %2,%0") + +(define_insn "iorsi3" + [(set (match_operand:SI 0 "register_operand" "=d,a") + (ior:SI (match_operand:SI 1 "register_operand" "%0,0") + (match_operand:SI 2 "nonmemory_operand" "di,ai")))] + "" + "or %2,%0") + +(define_insn "iorhi3" + [(set (match_operand:HI 0 "register_operand" "=d,a") + (ior:HI (match_operand:HI 1 "register_operand" "%0,0") + (match_operand:HI 2 "nonmemory_operand" "di,ai")))] + "" + "or %2,%0") + +(define_insn "iorqi3" + [(set (match_operand:QI 0 "register_operand" "=d,a") + (ior:QI (match_operand:QI 1 "register_operand" "%0,0") + (match_operand:QI 2 "nonmemory_operand" "di,ai")))] + "" + "or %2,%0") + +;;- xor instructions. + +(define_insn "" + [(set (match_operand:DI 0 "register_operand" "=d") + (xor:DI (match_operand:DI 1 "register_operand" "%0") + (match_operand:DI 2 "immediate_operand" "Fn")))] + "GET_CODE (operands[2]) == CONST_INT + || (GET_CODE (operands[2]) == CONST_DOUBLE + && CONST_DOUBLE_HIGH (operands[2]) == 0)" + "xor %2,%0") + +(define_insn "xordi3" + [(set (match_operand:DI 0 "register_operand" "=d") + (xor:DI (match_operand:DI 1 "register_operand" "%0") + (match_operand:DI 2 "register_operand" "d")))] + "" + "xor %2,%0") + +(define_insn "xorsi3" + [(set (match_operand:SI 0 "register_operand" "=d,a") + (xor:SI (match_operand:SI 1 "register_operand" "%0,0") + (match_operand:SI 2 "nonmemory_operand" "di,ai")))] + "" + "xor %2,%0") + +(define_insn "xorhi3" + [(set (match_operand:HI 0 "register_operand" "=d,a") + (xor:HI (match_operand:HI 1 "register_operand" "%0,0") + (match_operand:HI 2 "nonmemory_operand" "di,ai")))] + "" + "xor %2,%0") + +(define_insn "xorqi3" + [(set (match_operand:QI 0 "register_operand" "=d,a") + (xor:QI (match_operand:QI 1 "register_operand" "%0,0") + (match_operand:QI 2 "nonmemory_operand" "di,ai")))] + "" + "xor %2,%0") + +(define_insn "negdf2" + [(set (match_operand:DF 0 "register_operand" "=d") + (neg:DF (match_operand:DF 1 "register_operand" "d")))] + "" + "neg.d %1,%0") + +(define_insn "negsf2" + [(set (match_operand:SF 0 "register_operand" "=d") + (neg:SF (match_operand:SF 1 "register_operand" "d")))] + "" + "neg.s %1,%0") + +(define_insn "negdi2" + [(set (match_operand:DI 0 "register_operand" "=d") + (neg:DI (match_operand:DI 1 "register_operand" "d")))] + "" + "neg.l %1,%0") + +(define_insn "negsi2" + [(set (match_operand:SI 0 "register_operand" "=d,a") + (neg:SI (match_operand:SI 1 "register_operand" "d,a")))] + "" + "neg.w %1,%0") + +(define_insn "neghi2" + [(set (match_operand:HI 0 "register_operand" "=d,a") + (neg:HI (match_operand:HI 1 "register_operand" "d,a")))] + "" + "neg.h %1,%0") + +(define_insn "negqi2" + [(set (match_operand:QI 0 "register_operand" "=d") + (neg:QI (match_operand:QI 1 "register_operand" "d")))] + "" + "neg.b %1,%0") + +(define_insn "one_cmpldi2" + [(set (match_operand:DI 0 "register_operand" "=d") + (not:DI (match_operand:DI 1 "register_operand" "d")))] + "" + "not %1,%0") + +(define_insn "one_cmplsi2" + [(set (match_operand:SI 0 "register_operand" "=d,a") + (not:SI (match_operand:SI 1 "register_operand" "d,a")))] + "" + "not %1,%0") + +(define_insn "one_cmplhi2" + [(set (match_operand:HI 0 "register_operand" "=d,a") + (not:HI (match_operand:HI 1 "register_operand" "d,a")))] + "" + "not %1,%0") + +(define_insn "one_cmplqi2" + [(set (match_operand:QI 0 "register_operand" "=d,a") + (not:QI (match_operand:QI 1 "register_operand" "d,a")))] + "" + "not %1,%0") + +;;- shifts +;; +;; Convex shift instructions are logical shifts. +;; To make signed right shifts: +;; for SImode, sign extend to DImode and shift, works for 0..32 +;; for DImode, shift and then extend the sign, works for 0..63 -- but not 64 + +(define_insn "lshlsi3" + [(set (match_operand:SI 0 "register_operand" "=d,a") + (lshift:SI (match_operand:SI 1 "register_operand" "0,0") + (match_operand:SI 2 "nonmemory_operand" "di,ai")))] + "" + "* +{ + if (operands[2] == const1_rtx) + return \"add.w %0,%0\"; + else if (TARGET_C2 && S_REG_P (operands[0])) + return \"shf.w %2,%0\"; + else + return \"shf %2,%0\"; +}") + +(define_insn "ashlsi3" + [(set (match_operand:SI 0 "register_operand" "=d,a") + (ashift:SI (match_operand:SI 1 "register_operand" "0,0") + (match_operand:SI 2 "nonmemory_operand" "di,ai")))] + "" + "* +{ + if (operands[2] == const1_rtx) + return \"add.w %0,%0\"; + else if (TARGET_C2 && S_REG_P (operands[0])) + return \"shf.w %2,%0\"; + else + return \"shf %2,%0\"; +}") + +(define_expand "lshrsi3" + [(set (match_operand:SI 0 "register_operand" "") + (lshiftrt:SI (match_operand:SI 1 "register_operand" "") + (neg:SI (match_operand:SI 2 "nonmemory_operand" ""))))] + "" + "operands[2] = negate_rtx (SImode, operands[2]);") + +(define_insn "" + [(set + (match_operand:SI 0 "register_operand" "=d,a") + (lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0") + (neg:SI (match_operand:SI 2 "nonmemory_operand" "di,ai"))))] + "" + "* +{ + if (A_REG_P (operands[0])) + return \"shf %2,%0\"; + else if (TARGET_C2) + return \"shf.w %2,%0\"; + else + return \"ld.u #0,%0\;shf %2,%0\"; +}") + +(define_insn "" + [(set + (match_operand:SI 0 "register_operand" "=r") + (lshiftrt:SI (match_operand:SI 1 "register_operand" "0") + (match_operand:SI 2 "immediate_operand" "i")))] + "" + "* +{ + if (A_REG_P (operands[0])) + return \"shf #%n2,%0\"; + else if (TARGET_C2) + return \"shf.w #%n2,%0\"; + else + return \"ld.u #0,%0\;shf #%n2,%0\"; +}") + +(define_expand "ashrsi3" + [(set (match_operand:SI 0 "register_operand" "=d") + (ashiftrt:SI (match_operand:SI 1 "register_operand" "d") + (neg:SI (match_operand:SI 2 "nonmemory_operand" "di"))))] + "" + "operands[2] = negate_rtx (SImode, operands[2]);") + +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=&d") + (ashiftrt:SI (match_operand:SI 1 "register_operand" "d") + (neg:SI (match_operand:SI 2 "nonmemory_operand" "di"))))] + "" + "cvtw.l %1,%0\;shf %2,%0") + +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=&d") + (ashiftrt:SI (match_operand:SI 1 "register_operand" "d") + (match_operand:SI 2 "immediate_operand" "i")))] + "" + "cvtw.l %1,%0\;shf #%n2,%0") + +(define_insn "lshldi3" + [(set (match_operand:DI 0 "register_operand" "=d") + (lshift:DI (match_operand:DI 1 "register_operand" "0") + (match_operand:SI 2 "nonmemory_operand" "di")))] + "" + "shf %2,%0") + +(define_insn "ashldi3" + [(set (match_operand:DI 0 "register_operand" "=d") + (ashift:DI (match_operand:DI 1 "register_operand" "0") + (match_operand:SI 2 "nonmemory_operand" "di")))] + "" + "shf %2,%0") + +(define_expand "lshrdi3" + [(set (match_operand:DI 0 "register_operand" "=d") + (lshiftrt:DI (match_operand:DI 1 "register_operand" "0") + (neg:SI (match_operand:SI 2 "nonmemory_operand" "di"))))] + "" + "operands[2] = negate_rtx (SImode, operands[2]);") + +(define_insn "" + [(set (match_operand:DI 0 "register_operand" "=d") + (lshiftrt:DI (match_operand:DI 1 "register_operand" "0") + (neg:SI (match_operand:SI 2 "nonmemory_operand" "di"))))] + "" + "shf %2,%0") + +(define_insn "" + [(set (match_operand:DI 0 "register_operand" "=d") + (lshiftrt:DI (match_operand:DI 1 "register_operand" "0") + (match_operand:SI 2 "immediate_operand" "i")))] + "" + "shf #%n2,%0") + +;; signed a >> b is +;; ((a >> b) ^ signbit) - signbit +;; where signbit is (1 << 63) >> b + +(define_expand "ashrdi3" + [(match_operand:DI 0 "register_operand" "") + (match_operand:DI 1 "register_operand" "") + (match_operand:SI 2 "nonmemory_operand" "") + (match_dup 3)] + "" + " +{ + if (GET_CODE (operands[2]) == CONST_INT) + { + int rshift = INTVAL (operands[2]); + operands[3] = + force_reg (DImode, immed_double_const (1 << (63 - rshift), + 1 << (31 - rshift), DImode)); + } + else + { + operands[3] = + force_reg (DImode, immed_double_const (0, 1 << 31, DImode)); + emit_insn (gen_lshrdi3 (operands[3], operands[3], operands[2])); + } + + emit_insn (gen_lshrdi3 (operands[0], operands[1], operands[2])); + emit_insn (gen_rtx (SET, VOIDmode, operands[0], + gen_rtx (XOR, DImode, operands[0], operands[3]))); + emit_insn (gen_rtx (SET, VOIDmode, operands[0], + gen_rtx (MINUS, DImode, operands[0], operands[3]))); + DONE; +}") + +;; __builtin instructions + +(define_insn "sqrtdf2" + [(set (match_operand:DF 0 "register_operand" "=d") + (sqrt:DF (match_operand:DF 1 "register_operand" "0")))] + "TARGET_C2" + "sqrt.d %0") + +(define_insn "sqrtsf2" + [(set (match_operand:SF 0 "register_operand" "=d") + (sqrt:SF (match_operand:SF 1 "register_operand" "0")))] + "TARGET_C2" + "sqrt.s %0") + +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=d") + (minus:SI (ffs:SI (match_operand:SI 1 "register_operand" "d")) + (const_int 1)))] + "" + "tzc %1,%0\;le.w #32,%0\;jbrs.f .+6\;ld.w #-1,%0") + +(define_expand "ffssi2" + [(set (match_operand:SI 0 "register_operand" "=d") + (minus:SI (ffs:SI (match_operand:SI 1 "register_operand" "d")) + (const_int 1))) + (set (match_dup 0) + (plus:SI (match_dup 0) + (const_int 1)))] + "" + "") + +(define_insn "abssf2" + [(set (match_operand:SF 0 "register_operand" "=d") + (abs:SF (match_operand:SF 1 "register_operand" "0")))] + "" + "and #0x7fffffff,%0") + +(define_expand "absdf2" + [(set (subreg:DI (match_operand:DF 0 "register_operand" "=d") 0) + (and:DI (subreg:DI (match_operand:DF 1 "register_operand" "d") 0) + (match_dup 2)))] + "" + "operands[2] = force_reg (DImode, + immed_double_const (-1, 0x7fffffff, DImode));") + +;; Jumps + +(define_insn "jump" + [(set (pc) + (label_ref (match_operand 0 "" "")))] + "" + "jbr %l0") + +(define_insn "beq" + [(set (pc) + (if_then_else (eq (cc0) + (const_int 0)) + (label_ref (match_operand 0 "" "")) + (pc)))] + "" + "* return gen_cmp (operands[0], \"eq\", 't'); ") + +(define_insn "bne" + [(set (pc) + (if_then_else (ne (cc0) + (const_int 0)) + (label_ref (match_operand 0 "" "")) + (pc)))] + "" + "* return gen_cmp (operands[0], \"eq\", 'f'); ") + +(define_insn "bgt" + [(set (pc) + (if_then_else (gt (cc0) + (const_int 0)) + (label_ref (match_operand 0 "" "")) + (pc)))] + "" + "* return gen_cmp (operands[0], \"le\", 'f'); ") + +(define_insn "bgtu" + [(set (pc) + (if_then_else (gtu (cc0) + (const_int 0)) + (label_ref (match_operand 0 "" "")) + (pc)))] + "" + "* return gen_cmp (operands[0], \"leu\", 'f'); ") + +(define_insn "blt" + [(set (pc) + (if_then_else (lt (cc0) + (const_int 0)) + (label_ref (match_operand 0 "" "")) + (pc)))] + "" + "* return gen_cmp (operands[0], \"lt\", 't'); ") + +(define_insn "bltu" + [(set (pc) + (if_then_else (ltu (cc0) + (const_int 0)) + (label_ref (match_operand 0 "" "")) + (pc)))] + "" + "* return gen_cmp (operands[0], \"ltu\", 't'); ") + +(define_insn "bge" + [(set (pc) + (if_then_else (ge (cc0) + (const_int 0)) + (label_ref (match_operand 0 "" "")) + (pc)))] + "" + "* return gen_cmp (operands[0], \"lt\", 'f'); ") + +(define_insn "bgeu" + [(set (pc) + (if_then_else (geu (cc0) + (const_int 0)) + (label_ref (match_operand 0 "" "")) + (pc)))] + "" + "* return gen_cmp (operands[0], \"ltu\", 'f'); ") + +(define_insn "ble" + [(set (pc) + (if_then_else (le (cc0) + (const_int 0)) + (label_ref (match_operand 0 "" "")) + (pc)))] + "" + "* return gen_cmp (operands[0], \"le\", 't'); ") + +(define_insn "bleu" + [(set (pc) + (if_then_else (leu (cc0) + (const_int 0)) + (label_ref (match_operand 0 "" "")) + (pc)))] + "" + "* return gen_cmp (operands[0], \"leu\", 't'); ") + +(define_insn "" + [(set (pc) + (if_then_else (eq (cc0) + (const_int 0)) + (pc) + (label_ref (match_operand 0 "" ""))))] + "" + "* return gen_cmp (operands[0], \"eq\", 'f'); ") + +(define_insn "" + [(set (pc) + (if_then_else (ne (cc0) + (const_int 0)) + (pc) + (label_ref (match_operand 0 "" ""))))] + "" + "* return gen_cmp (operands[0], \"eq\", 't'); ") + +(define_insn "" + [(set (pc) + (if_then_else (gt (cc0) + (const_int 0)) + (pc) + (label_ref (match_operand 0 "" ""))))] + "" + "* return gen_cmp (operands[0], \"le\", 't'); ") + +(define_insn "" + [(set (pc) + (if_then_else (gtu (cc0) + (const_int 0)) + (pc) + (label_ref (match_operand 0 "" ""))))] + "" + "* return gen_cmp (operands[0], \"leu\", 't'); ") + +(define_insn "" + [(set (pc) + (if_then_else (lt (cc0) + (const_int 0)) + (pc) + (label_ref (match_operand 0 "" ""))))] + "" + "* return gen_cmp (operands[0], \"lt\", 'f'); ") + +(define_insn "" + [(set (pc) + (if_then_else (ltu (cc0) + (const_int 0)) + (pc) + (label_ref (match_operand 0 "" ""))))] + "" + "* return gen_cmp (operands[0], \"ltu\", 'f'); ") + +(define_insn "" + [(set (pc) + (if_then_else (ge (cc0) + (const_int 0)) + (pc) + (label_ref (match_operand 0 "" ""))))] + "" + "* return gen_cmp (operands[0], \"lt\", 't'); ") + +(define_insn "" + [(set (pc) + (if_then_else (geu (cc0) + (const_int 0)) + (pc) + (label_ref (match_operand 0 "" ""))))] + "" + "* return gen_cmp (operands[0], \"ltu\", 't'); ") + +(define_insn "" + [(set (pc) + (if_then_else (le (cc0) + (const_int 0)) + (pc) + (label_ref (match_operand 0 "" ""))))] + "" + "* return gen_cmp (operands[0], \"le\", 'f'); ") + +(define_insn "" + [(set (pc) + (if_then_else (leu (cc0) + (const_int 0)) + (pc) + (label_ref (match_operand 0 "" ""))))] + "" + "* return gen_cmp (operands[0], \"leu\", 'f'); ") + +;; - Calls +;; +;; arg count word may be omitted to save a push and let gcc try to +;; combine the arg list pop. RETURN_POPS_ARGS from tm.h decides this. + +(define_insn "call" + [(call (match_operand:QI 0 "memory_operand" "m") + (match_operand:SI 1 "general_operand" "g"))] + "" + "* return output_call (insn, operands[0], operands[1]);") + +(define_insn "call_value" + [(set (match_operand 0 "" "=g") + (call (match_operand:QI 1 "memory_operand" "m") + (match_operand:SI 2 "general_operand" "g")))] + "" + "* return output_call (insn, operands[1], operands[2]);") + +(define_insn "return" + [(return)] + "" + "rtn") + +(define_insn "nop" + [(const_int 0)] + "" + "nop") + +(define_insn "tablejump" + [(set (pc) (match_operand:SI 0 "address_operand" "p")) + (use (label_ref (match_operand 1 "" "")))] + "" + "jmp %a0") + +(define_insn "indirect_jump" + [(set (pc) (match_operand:SI 0 "address_operand" "p"))] + "" + "jmp %a0") + +;;- Local variables: +;;- mode:emacs-lisp +;;- comment-start: ";;- " +;;- eval: (set-syntax-table (copy-sequence (syntax-table))) +;;- eval: (modify-syntax-entry ?[ "(]") +;;- eval: (modify-syntax-entry ?] ")[") +;;- eval: (modify-syntax-entry ?{ "(}") +;;- eval: (modify-syntax-entry ?} "){") +;;- End: |