diff options
| author | Andrew Lee <alee14498@protonmail.com> | 2021-08-15 00:34:05 -0400 |
|---|---|---|
| committer | Andrew Lee <alee14498@protonmail.com> | 2021-08-15 00:34:05 -0400 |
| commit | 60cc83bf91bfc9bb02f6304b5d6c8234ba6d210f (patch) | |
| tree | fdc0be85a1ca35e34c3ae2c805fe9b718e3c1091 /gcc-1.40/config/convex.md | |
| parent | dd8dfab51b832a654365ed00c06bf802ff628bfa (diff) | |
| download | linux-0.01-distro-60cc83bf91bfc9bb02f6304b5d6c8234ba6d210f.tar.gz linux-0.01-distro-60cc83bf91bfc9bb02f6304b5d6c8234ba6d210f.tar.bz2 linux-0.01-distro-60cc83bf91bfc9bb02f6304b5d6c8234ba6d210f.zip | |
Diffstat (limited to 'gcc-1.40/config/convex.md')
| -rw-r--r-- | gcc-1.40/config/convex.md | 1266 |
1 files changed, 1266 insertions, 0 deletions
diff --git a/gcc-1.40/config/convex.md b/gcc-1.40/config/convex.md new file mode 100644 index 0000000..97d874d --- /dev/null +++ b/gcc-1.40/config/convex.md @@ -0,0 +1,1266 @@ +;;- Machine description for GNU compiler +;;- Convex 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 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, 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. + +;; Put tstsi first among test insns so it matches a CONST_INT operand. + +(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_insn "tstdi" + [(set (cc0) + (match_operand:DI 0 "register_operand" "d")) + (clobber (reg:DI 1))] + "" + "* +{ + output_asm_insn (\"ld.l #0,s1\"); + return set_cmp (operands[0], gen_rtx (REG, DImode, 1), 'l'); +}") + +(define_expand "tstdf" + [(set (cc0) + (compare (match_operand:DF 0 "register_operand" "d") + (match_dup 1)))] + "" + "operands[1] = force_reg (DFmode, dconst0_rtx);") + +(define_insn "tstsf" + [(set (cc0) + (match_operand:SF 0 "register_operand" "d"))] + "" + "* return set_cmp (operands[0], fconst0_rtx, 's');") + +;; Put cmpsi first among compare insns so it matches two CONST_INT operands. + +(define_insn "cmpsi" + [(set (cc0) + (compare (match_operand:SI 0 "nonmemory_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 "nonmemory_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 "" + [(set (cc0) + (compare (sign_extend:SI (match_operand:QI 0 "register_operand" "d")) + (sign_extend:SI (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');") + +(define_insn "movdf" + [(set (match_operand:DF 0 "general_operand" "=g,d") + (match_operand:DF 1 "general_operand" "d,gG"))] + "" + "* +{ + 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 + 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,gG"))] + "" + "* +{ + 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)") + +(define_insn "movsi" + [(set (match_operand:SI 0 "general_operand" "=g,r,<") + (match_operand:SI 1 "general_operand" "r,g,io"))] + "" + "* +{ + 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 "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 "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 "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 "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 unsigned. +;; 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 +;; +;; It is very sad that DImode right shift 64 fails, but I don't see +;; any reasonable way to handle it. ANSI only requires up to 63. + +(define_insn "" + [(set (match_operand:SI 0 "register_operand" "=r") + (ashift:SI (match_operand:SI 1 "register_operand" "0") + (match_operand:SI 2 "immediate_operand" "i")))] + "INTVAL (operands[2]) >= 0" + "* +{ + 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") + (ashift:SI (match_operand:SI 1 "register_operand" "0") + (match_operand:SI 2 "nonmemory_operand" "di")))] + "" + "* +{ + if (operands[2] == const1_rtx) + return \"add.w %0,%0\"; + else if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0) + return TARGET_C2 ? \"shf.w %2,%0\" : \"shf %2,%0\"; + else + return \"cvtw.l %0,%0\;shf %2,%0\"; +}") + +(define_expand "ashrsi3" + [(set (match_operand:SI 0 "register_operand" "=d") + (ashift:SI (match_operand:SI 1 "register_operand" "0") + (match_operand:SI 2 "nonmemory_operand" "di")))] + "" + "operands[2] = negate_rtx (SImode, operands[2]);") + +(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\"; + if (S_REG_P (operands[0])) + { + if (TARGET_C2) + return \"shf.w %2,%0\"; + else if (GET_CODE (operands[2]) == CONST_INT + && INTVAL (operands[2]) >= 0) + return \"shf %2,%0\"; + else + return \"ld.u #0,%0\;shf %2,%0\"; + } + return \"shf %2,%0\"; +}") + +(define_expand "lshrsi3" + [(set (match_operand:SI 0 "register_operand" "=d") + (lshift:SI (match_operand:SI 1 "register_operand" "0") + (match_operand:SI 2 "nonmemory_operand" "di")))] + "" + "operands[2] = negate_rtx (SImode, operands[2]);") + +;; signed a >> b is +;; ((a >> b) ^ signbit) - signbit +;; where signbit is (1 << 63) >> b + +(define_expand "ashldi3" + [(match_operand:DI 0 "register_operand" "=d") + (match_operand:DI 1 "register_operand" "0") + (match_operand:SI 2 "nonmemory_operand" "di") + (match_dup 3)] + "" + " +{ + if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) >= 0) + emit_insn (gen_rtx (SET, VOIDmode, operands[0], + gen_rtx (LSHIFT, DImode, operands[1], operands[2]))); + else if (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0) + { + int rshift = - INTVAL (operands[2]); + operands[3] = force_reg + (DImode, + immed_double_const (1 << (63 - rshift), 1 << (31 - rshift), DImode)); + emit_insn (gen_rtx (SET, VOIDmode, operands[0], + gen_rtx (LSHIFT, DImode, 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]))); + } + else + { + operands[3] = + force_reg (DImode, immed_double_const (0, 1 << 31, DImode)); + emit_insn (gen_rtx (SET, VOIDmode, operands[0], + gen_rtx (LSHIFT, DImode, operands[1], operands[2]))); + emit_insn (gen_rtx (SET, VOIDmode, operands[3], + gen_rtx (LSHIFT, DImode, operands[3], 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; +}") + +(define_expand "ashrdi3" + [(match_operand:DI 0 "register_operand" "=d") + (match_operand:DI 1 "register_operand" "0") + (match_operand:SI 2 "nonmemory_operand" "di")] + "" + " +{ + emit_insn (gen_ashldi3 (operands[0], operands[1], + negate_rtx (SImode, operands[2]))); + DONE; +}") + +(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_expand "lshrdi3" + [(set (match_operand:DI 0 "register_operand" "=d") + (lshift:DI (match_operand:DI 1 "register_operand" "0") + (match_operand:SI 2 "nonmemory_operand" "di")))] + "" + "operands[2] = negate_rtx (SImode, operands[2]);") + +;; __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));") + +(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 "general_operand" "g") + (match_operand:SI 1 "general_operand" "g"))] + "" + "* +{ + if (! RETURN_POPS_ARGS (ignoreme)) + { + if (operands[1] == const0_rtx) + return \"calls %0\"; + if (! reg_mentioned_p (arg_pointer_rtx, operands[0])) + return \"mov sp,ap\;calls %0\;ld.w 12(fp),ap\"; + operands[0] = XEXP (operands[0], 0); + return \"ld.w %0,a1\;mov sp,ap\;calls (a1)\;ld.w 12(fp),ap\"; + } + operands[1] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[1]) + 3)/ 4); + if (! reg_mentioned_p (arg_pointer_rtx, operands[0])) + return \"mov sp,ap\;pshea %a1\;calls %0\;ld.w 12(fp),ap\;add.w #4*%a1+4,sp\"; + operands[0] = XEXP (operands[0], 0); + return \"ld.w %0,a1\;mov sp,ap\;pshea %a1\;calls (a1)\;ld.w 12(fp),ap\;add.w #4*%a1+4,sp\"; +}") + +(define_insn "call_value" + [(set (match_operand 0 "" "=g") + (call (match_operand:QI 1 "general_operand" "g") + (match_operand:SI 2 "general_operand" "g")))] + "" + "* +{ + if (! RETURN_POPS_ARGS (ignoreme)) + { + if (operands[2] == const0_rtx) + return \"calls %1\"; + if (! reg_mentioned_p (arg_pointer_rtx, operands[1])) + return \"mov sp,ap\;calls %1\;ld.w 12(fp),ap\"; + operands[1] = XEXP (operands[1], 0); + return \"ld.w %1,a1\;mov sp,ap\;calls (a1)\;ld.w 12(fp),ap\"; + } + operands[2] = gen_rtx (CONST_INT, VOIDmode, (INTVAL (operands[2]) + 3) / 4); + if (! reg_mentioned_p (arg_pointer_rtx, operands[1])) + return \"mov sp,ap\;pshea %a2\;calls %1\;ld.w 12(fp),ap\;add.w #4*%a2+4,sp\"; + operands[1] = XEXP (operands[1], 0); + return \"ld.w %1,a1\;mov sp,ap\;pshea %a2\;calls (a1)\;ld.w 12(fp),ap\;add.w #4*%a2+4,sp\"; +}") + +(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") + +;; - fix up the code generated for bit field tests + +;; cc0 = (x >> k1) & k2 --> cc0 = x & (k2 << k1) +;; cc0 = (x << k1) & k2 --> cc0 = x & (k2 >> k1) +;; provided k2 and (k2 << k1) don't include the sign bit + +(define_peephole + [(set (match_operand:SI 0 "register_operand" "r") + (lshift:SI (match_dup 0) + (match_operand 1 "immediate_operand" "i"))) + (set (match_dup 0) + (and:SI (match_dup 0) + (match_operand 2 "immediate_operand" "i"))) + (set (cc0) (match_dup 0))] + "dead_or_set_p (insn, operands[0]) + && GET_CODE (operands[1]) == CONST_INT + && GET_CODE (operands[2]) == CONST_INT + && INTVAL (operands[2]) >= 0 + && (INTVAL (operands[2]) << INTVAL (operands[1])) >= 0" + "* +{ + operands[2] = gen_rtx (CONST_INT, VOIDmode, + INTVAL (operands[2]) >> INTVAL (operands[1])); + output_asm_insn (\"and %2,%0\", operands); + return set_cmp (operands[0], const0_rtx, 'w'); +}") + +;; same as above where x is (y & 0xff...) caused by a zero extend + +(define_peephole + [(set (match_operand:SI 0 "register_operand" "r") + (zero_extend:SI (match_operand 1 "register_operand" "0"))) + (set (match_dup 0) + (lshift:SI (match_dup 0) + (match_operand 2 "immediate_operand" "i"))) + (set (match_dup 0) + (and:SI (match_dup 0) + (match_operand 3 "immediate_operand" "i"))) + (set (cc0) (match_dup 0))] + "dead_or_set_p (insn, operands[0]) + && REGNO (operands[0]) == REGNO (operands[1]) + && GET_CODE (operands[2]) == CONST_INT + && GET_CODE (operands[3]) == CONST_INT + && (INTVAL (operands[3]) << INTVAL (operands[2])) >= 0" + "* +{ + operands[3] = gen_rtx (CONST_INT, VOIDmode, + (INTVAL (operands[3]) >> INTVAL (operands[2])) & + ~((-1) << GET_MODE_BITSIZE (GET_MODE (operands[1])))); + output_asm_insn (\"and %3,%0\", operands); + return set_cmp (operands[0], const0_rtx, 'w'); +}") + +;;- 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: + |
