home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-12-03 | 48.6 KB | 1,958 lines |
- ;; Mips.md Naive version of Machine Description for MIPS
- ;; Contributed by A. Lichnewsky, lich@inria.inria.fr
- ;; Changes by Michael Meissner, meissner@osf.org
- ;; Copyright (C) 1989, 1990 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.
-
- ;;
- ;;------------------------------------------------------------------------
- ;;
-
- ;;
- ;; ....................
- ;;
- ;; Peephole Optimizations for
- ;;
- ;; ARITHMETIC
- ;;
- ;; ....................
- ;;
- ;;- The following peepholes are
- ;;- motivated by the fact that
- ;;- stack movement result in some
- ;;- cases in embarrassing sequences
- ;;- of addiu SP,SP,int
- ;;- addiu SP,SP,other_int
-
- ;;- --------------------
- ;;- REMARK: this would be done better
- ;;- by analysis of dependencies in
- ;;- basic blocks, prior to REG ALLOC,
- ;;- and simplification of trees:
- ;;- (+ (+ REG const) const)
- ;;- -> (+ REG newconst)
- ;;- --------------------
- ;;- Merged peephole code from
- ;;- raeburn@ATHENA.MIT.EDU
-
- (define_peephole
- [(set (match_operand:SI 0 "register_operand" "=r")
- (match_operator 1 "additive_op"
- [(match_operand:SI 2 "register_operand" "r")
- (match_operand:SI 3 "small_int" "I")]))
- (set (match_operand:SI 4 "register_operand" "=r")
- (match_operator 5 "additive_op"
- [(match_dup 0)
- (match_operand:SI 6 "small_int" "I")]))]
- "(REGNO (operands[0]) == REGNO (operands[4])
- || dead_or_set_p (insn, operands[0]))"
- "*
- {
- int addend;
- /* compute sum, with signs */
- addend = INTVAL (operands[3]) * (GET_CODE (operands[1]) == PLUS ? 1 : -1);
- addend += INTVAL (operands[6]) * (GET_CODE (operands[5]) == PLUS ? 1 : -1);
- if (addend != 0)
- {
- operands[0] = gen_rtx (CONST_INT, VOIDmode, addend);
- return \"addi%:\\t%4,%2,%0\";
- }
- /* value is zero; copy */
- if (REGNO (operands[4]) != REGNO (operands[2]))
- return \"add%:\\t%4,%2,$0\";
- /* copying to self; punt */
- return \" # null operation: additive operands cancel (%0,%2)\";
- }")
-
- ;;
- ;; ....................
- ;;
- ;; ARITHMETIC
- ;;
- ;; ....................
- ;;
-
- (define_insn "adddf3"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (plus:DF (match_operand:DF 1 "register_operand" "f")
- (match_operand:DF 2 "register_operand" "f")))]
- ""
- "add.d\\t%0,%1,%2")
-
- (define_insn "addsf3"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (plus:SF (match_operand:SF 1 "register_operand" "f")
- (match_operand:SF 2 "register_operand" "f")))]
- ""
- "add.s\\t%0,%1,%2")
-
- ;; The following is generated when omiting the frame pointer
- ;; and for referencing large auto arrays during optimization.
-
- (define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (plus:SI (match_operand:SI 1 "register_operand" "%r")
- (match_operand:SI 2 "immediate_operand" "i")))]
- "operands[1] == stack_pointer_rtx || operands[1] == frame_pointer_rtx"
- "*
- {
- int number;
- if (GET_CODE (operands[2]) != CONST_INT)
- return \"add%:\\t%0,%1,%2\";
-
- number = INTVAL (operands[2]);
- if (((unsigned) (number + 0x8000) > 0xffff))
- {
- operands[3] = gen_rtx (REG, SImode, 1); /* assembler temp. */
- return \".set\\tnoat\\n\\tli\\t%3,%2\\n\\tadd%:\\t%0,%1,%3\\n\\t.set\\tat\";
- }
-
- return (number < 0) ? \"sub%:\\t%0,%1,%n2\" : \"add%:\\t%0,%1,%2\";
- }")
-
- (define_insn "addsi3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (plus:SI (match_operand:SI 1 "arith_operand" "%r")
- (match_operand:SI 2 "arith_operand" "rI")))]
- ""
- "*
- {
- return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
- ? \"sub%:\\t%0,%1,%n2\"
- : \"add%:\\t%0,%1,%2\";
- }")
-
-
- ;;- All kinds of subtract instructions.
-
- (define_insn "subdf3"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (minus:DF (match_operand:DF 1 "register_operand" "f")
- (match_operand:DF 2 "register_operand" "f")))]
- ""
- "sub.d\\t%0,%1,%2")
-
- (define_insn "subsf3"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (minus:SF (match_operand:SF 1 "register_operand" "f")
- (match_operand:SF 2 "register_operand" "f")))]
- ""
- "sub.s\\t%0,%1,%2")
-
- ;; The following is generated when omiting the frame pointer
- ;; and for referencing large auto arrays during optimization.
-
- (define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (minus:SI (match_operand:SI 1 "register_operand" "%r")
- (match_operand:SI 2 "immediate_operand" "i")))]
- "operands[1] == stack_pointer_rtx || operands[1] == frame_pointer_rtx"
- "*
- {
- int number;
- if (GET_CODE (operands[2]) != CONST_INT)
- return \"sub%:\\t%0,%1,%2\";
-
- number = INTVAL (operands[2]);
- if (((unsigned) (number + 0x8000) > 0xffff))
- {
- operands[3] = gen_rtx (REG, SImode, 1); /* assembler temp. */
- return \".set\\tnoat\\n\\tli\\t%3,%2\\n\\tsub%:\\t%0,%1,%3\\n\\t.set\\tat\";
- }
-
- return (number < 0) ? \"add%:\\t%0,%1,%n2\" : \"sub%:\\t%0,%1,%2\";
- }")
-
- (define_insn "subsi3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (minus:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "arith_operand" "rI")))]
- ""
- "*
- {
- return (GET_CODE (operands[2]) == CONST_INT && INTVAL (operands[2]) < 0)
- ? \"add%:\\t%0,%1,%n2\"
- : \"sub%:\\t%0,%1,%2\";
- }")
-
-
- ;;- Multiply instructions.
-
- (define_insn "muldf3"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (mult:DF (match_operand:DF 1 "register_operand" "f")
- (match_operand:DF 2 "register_operand" "f")))]
- ""
- "mul.d\\t%0,%1,%2")
-
- (define_insn "mulsf3"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (mult:SF (match_operand:SF 1 "register_operand" "f")
- (match_operand:SF 2 "register_operand" "f")))]
- ""
- "mul.s\\t%0,%1,%2")
-
- (define_insn "mulsi3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (mult:SI (match_operand:SI 1 "arith_operand" "%r")
- (match_operand:SI 2 "arith_operand" "rI")))]
- ""
- "mul\\t%0,%1,%2")
-
-
- ;;- Divide instructions.
-
- (define_insn "divdf3"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (div:DF (match_operand:DF 1 "register_operand" "f")
- (match_operand:DF 2 "register_operand" "f")))]
- ""
- "div.d\\t%0,%1,%2")
-
- (define_insn "divsf3"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (div:SF (match_operand:SF 1 "register_operand" "f")
- (match_operand:SF 2 "register_operand" "f")))]
- ""
- "div.s\\t%0,%1,%2")
-
- (define_insn "divmodsi4"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (div:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "arith_operand" "rI")))
- (set (match_operand:SI 3 "register_operand" "=r")
- (mod:SI (match_dup 1)
- (match_dup 2)))]
- ""
- "div\\t$0,%1,%2\\n\\tmflo\\t%0\\t\\t#quotient\\n\\tmfhi\\t%3\\t\\t#remainder")
-
- (define_insn "divsi3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (div:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "arith_operand" "rI")))]
- ""
- "div\\t%0,%1,%2")
-
- (define_insn "udivmodsi4"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (udiv:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "arith_operand" "rI")))
- (set (match_operand:SI 3 "register_operand" "=r")
- (umod:SI (match_dup 1)
- (match_dup 2)))]
- ""
- "divu\\t$0,%1,%2\\n\\tmflo\\t%0\\t\\t#quotient\\n\\tmfhi\\t%3\\t\\t#remainder")
-
- (define_insn "udivsi3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (udiv:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "arith_operand" "rI")))]
- ""
- "divu\\t%0,%1,%2")
-
-
- ;; Remainder instructions
-
-
- (define_insn "modsi3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (mod:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "arith_operand" "rI")))]
- ""
- "rem\\t%0,%1,%2")
-
- (define_insn "umodsi3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (umod:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "arith_operand" "rI")))]
- ""
- "remu\\t%0,%1,%2")
-
-
- ;; Absoluate value instructions -- Don't use the integer abs,
- ;; since that signals an exception on -2147483648 (sigh).
-
- (define_insn "abssf2"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (abs:SF (match_operand:SF 1 "register_operand" "f")))]
- ""
- "abs.s\\t%0,%1")
-
- (define_insn "absdf2"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (abs:DF (match_operand:DF 1 "register_operand" "f")))]
- ""
- "abs.d\\t%0,%1")
-
- ;;
- ;; ....................
- ;;
- ;; LOGICAL
- ;;
- ;; ....................
- ;;
-
- (define_insn "anddi3"
- [(set (match_operand:DI 0 "register_operand" "=&r")
- (and:DI (match_operand:DI 1 "register_operand" "r")
- (match_operand:DI 2 "register_operand" "r")))]
- ""
- "and\\t%0,%1,%2\;and\\t%D0,%D1,%D2")
-
- (define_insn "andsi3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (and:SI (match_operand:SI 1 "uns_arith_operand" "%r")
- (match_operand:SI 2 "uns_arith_operand" "rK")))]
- ""
- "*
- {
- return (GET_CODE (operands[2]) == CONST_INT)
- ? \"andi\\t%0,%1,%x2\"
- : \"and\\t%0,%1,%2\";
- }")
-
-
- ;; Simple hack to recognize the "nor" instruction on the MIPS
- ;; [rms: I don't think the following is actually required.]
- ;; This must appear before the normal or patterns, so that the
- ;; combiner will correctly fold things.
-
- (define_insn ""
- [(set (match_operand:DI 0 "register_operand" "=r")
- (not:DI (ior:DI (match_operand:DI 1 "register_operand" "r")
- (match_operand:DI 2 "register_operand" "r"))))]
- ""
- "nor\\t%0,%1,%2\;nor\\t%D0,%D1,%D2")
-
- (define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (not:SI (ior:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "register_operand" "r"))))]
- ""
- "nor\\t%0,%1,%2")
-
- (define_insn "iordi3"
- [(set (match_operand:DI 0 "register_operand" "=&r")
- (ior:DI (match_operand:DI 1 "register_operand" "r")
- (match_operand:DI 2 "register_operand" "r")))]
- ""
- "or\\t%0,%1,%2\;or\\t%D0,%D1,%D2")
-
- (define_insn "iorsi3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (ior:SI (match_operand:SI 1 "uns_arith_operand" "%r")
- (match_operand:SI 2 "uns_arith_operand" "rJ")))]
- ""
- "*
- {
- return (GET_CODE (operands[2]) == CONST_INT)
- ? \"ori\\t%0,%1,%x2\"
- : \"or\\t%0,%1,%2\";
- }")
-
- (define_insn "xordi3"
- [(set (match_operand:DI 0 "register_operand" "=&r")
- (xor:DI (match_operand:DI 1 "register_operand" "r")
- (match_operand:DI 2 "register_operand" "r")))]
- ""
- "xor\\t%0,%1,%2\;xor\\t%D0,%D1,%D2")
-
- (define_insn "xorsi3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (xor:SI (match_operand:SI 1 "uns_arith_operand" "%r")
- (match_operand:SI 2 "uns_arith_operand" "rK")))]
- ""
- "*
- {
- return (GET_CODE (operands[2]) == CONST_INT)
- ? \"xori\\t%0,%1,%x2\"
- : \"xor\\t%0,%1,%2\";
- }")
-
- ;;
- ;; ....................
- ;;
- ;; TRUNCATION
- ;;
- ;; ....................
-
- ;; 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" "=r")
- (truncate:QI (match_operand:SI 1 "register_operand" "r")))]
- ""
- "andi\\t%0,%1,0xff\\t#truncsiqi2\\t %1 -> %0")
-
- (define_insn "truncsihi2"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (truncate:HI (match_operand:SI 1 "register_operand" "r")))]
- ""
- "*
- output_asm_insn (\"sll\\t%0,%1,0x10\\t#truncsihi2\\t %1 -> %0\",
- operands);
- return \"sra\\t%0,%0,0x10\\t#truncsihi2\\t %1 -> %0\";
- ")
-
- (define_insn "trunchiqi2"
- [(set (match_operand:QI 0 "register_operand" "=r")
- (truncate:QI (match_operand:HI 1 "register_operand" "r")))]
- ""
- "andi\\t%0,%1,0xff\\t#trunchiqi2\\t %1 -> %0")
-
- (define_insn "truncdfsf2"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (float_truncate:SF (match_operand:DF 1 "register_operand" "f")))]
- ""
- "cvt.s.d\\t%0,%1\\t#truncdfsf2\\t %1 -> %0")
-
- ;;
- ;; ....................
- ;;
- ;; ZERO EXTENSION
- ;;
- ;; ....................
-
- ;; Extension insns.
- ;; Those for integer source operand
- ;; are ordered widest source type first.
-
-
-
- (define_insn "zero_extendhisi2"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (zero_extend:SI (match_operand:HI 1 "general_operand" "r,m")))]
- ""
- "*
- {
- if (which_alternative == 0)
- {
- output_asm_insn (\"sll\\t%0,%1,0x10\\t#zero_extendhisi2\\t %1 -> %0\",
- operands);
- return \"srl\\t%0,%0,0x10\\t#zero_extendhisi2\\t %1 -> %0\";
- }
- else
- return \"lhu\\t%0,%1\\t#zero extendhisi2 %1 -> %0\";
- }")
-
- (define_insn "zero_extendqihi2"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (zero_extend:HI (match_operand:QI 1 "register_operand" "r")))]
- ""
- "*
- output_asm_insn (\"sll\\t%0,%1,0x18\\t#zero_extendqihi2\\t %1 -> %0\",
- operands);
- return \"srl\\t%0,%0,0x18\\t#zero_extendqihi2\\t %1 -> %0\";
- ")
-
-
- (define_insn "zero_extendqisi2"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (zero_extend:SI (match_operand:QI 1 "general_operand" "r,m")))]
- ""
- "*
- {
- if (which_alternative == 0)
- {
- return \"andi\\t%0,%1,0xff\\t#zero_extendqisi2\\t %1 -> %0\";
- }
- else
- return \"lbu\\t%0,%1\\t#zero extendqisi2 %1 -> %0\";
- }")
-
-
- ;;
- ;; ....................
- ;;
- ;; SIGN EXTENSION
- ;;
- ;; ....................
-
- ;; Extension insns.
- ;; Those for integer source operand
- ;; are ordered widest source type first.
-
-
-
- (define_insn "extendhisi2"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (sign_extend:SI (match_operand:HI 1 "general_operand" "r,m")))]
- ""
- "*
- {
- if (which_alternative == 0)
- {
- output_asm_insn (\"sll\\t%0,%1,0x10\\t#sign extendhisi2\\t %1 -> %0\",
- operands);
- return \"sra\\t%0,%0,0x10\\t#sign extendhisi2\\t %1 -> %0\";
- }
- else
- return \"lh\\t%0,%1\\t#sign extendhisi2 %1 -> %0\";
- }")
-
- (define_insn "extendqihi2"
- [(set (match_operand:HI 0 "register_operand" "=r")
- (sign_extend:HI (match_operand:QI 1 "register_operand" "r")))]
- ""
- "*
- output_asm_insn (\"sll\\t%0,%1,0x18\\t#sign extendqihi2\\t %1 -> %0\",
- operands);
- return \"sra\\t%0,%0,0x18\\t#sign extendqihi2\\t %1 -> %0\";
- ")
-
-
- (define_insn "extendqisi2"
- [(set (match_operand:SI 0 "register_operand" "=r,r")
- (sign_extend:SI (match_operand:QI 1 "general_operand" "r,m")))]
- ""
- "*
- {
- if (which_alternative == 0)
- {
- output_asm_insn (\"sll\\t%0,%1,0x18\\t#sign extendqisi2\\t %1 -> %0\",
- operands);
- return \"sra\\t%0,%0,0x18\\t#sign extendqisi2\\t %1 -> %0\";
- }
- else
- return \"lb\\t%0,%1\\t#sign extendqisi2 %1 -> %0\";
- }")
-
-
- (define_insn "extendsfdf2"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (float_extend:DF (match_operand:SF 1 "register_operand" "f")))]
- ""
- "cvt.d.s\\t%0,%1\\t#extendsfdf2\\t %1 -> %0")
-
-
- ;;
- ;; ....................
- ;;
- ;; CONVERSIONS
- ;;
- ;; ....................
-
-
- (define_insn "fix_truncdfsi2_internal"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (fix:DF (match_operand:DF 1 "register_operand" "f")))
- (clobber (match_operand:SI 2 "register_operand" "r"))]
- ""
- "trunc.w.d %0,%1,%2")
-
- (define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
- ""
- "mfc1\\t%0,%1")
-
- (define_expand "fix_truncdfsi2"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (fix:SI (fix:DF (match_operand:DF 1 "register_operand" "f"))))]
- ""
- "
- {
- rtx reg1 = gen_reg_rtx (DFmode); /* fp reg that gets trunc result */
- rtx reg2 = gen_reg_rtx (SImode); /* gp reg that saves FP status bits */
- emit_insn (gen_fix_truncdfsi2_internal (reg1, operands[1], reg2));
- operands[1] = reg1;
- /* Fall through and generate default code */
- }")
-
- (define_insn "fix_truncsfsi2_internal"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (fix:SF (match_operand:SF 1 "register_operand" "f")))
- (clobber (match_operand:SI 2 "register_operand" "r"))]
- ""
- "trunc.w.s %0,%1,%2")
-
- (define_insn ""
- [(set (match_operand:SI 0 "register_operand" "=r")
- (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
- ""
- "mfc1\\t%0,%1")
-
- (define_expand "fix_truncsfsi2"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (fix:SI (fix:SF (match_operand:SF 1 "register_operand" "f"))))]
- ""
- "
- {
- rtx reg1 = gen_reg_rtx (SFmode); /* fp reg that gets trunc result */
- rtx reg2 = gen_reg_rtx (SImode); /* gp reg that saves FP status bits */
- emit_insn (gen_fix_truncsfsi2_internal (reg1, operands[1], reg2));
- operands[1] = reg1;
- /* Fall through and generate default code */
- }")
-
- (define_insn "floatsidf2"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (float:DF (match_operand:SI 1 "register_operand" "r")))]
- ""
- "mtc1\\t%1,%0\\t\\t#floatsidf2\\t%1 -> %0\;cvt.d.w\\t%0,%0")
-
-
- (define_insn "floatsisf2"
- [(set (match_operand:SF 0 "register_operand" "=f")
- (float:SF (match_operand:SI 1 "register_operand" "r")))]
- ""
- "mtc1\\t%1,%0\\t\\t#floatsisf2\\t%1 -> %0\;cvt.s.w\\t%0,%0")
-
- (define_expand "fixuns_truncdfsi2"
- [(set (match_operand:SI 0 "register_operand" "")
- (unsigned_fix:SI (match_operand:DF 1 "register_operand" "")))]
- ""
- "
- {
- rtx reg1 = gen_reg_rtx (DFmode);
- rtx reg2 = gen_reg_rtx (DFmode);
- rtx reg3 = gen_reg_rtx (SImode);
- rtx label1 = gen_label_rtx ();
- rtx label2 = gen_label_rtx ();
- REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
-
- if (reg1) /* turn off complaints about unreached code */
- {
- emit_move_insn (reg1, immed_real_const_1 (offset, DFmode));
- do_pending_stack_adjust ();
- emit_insn (gen_rtx (SET, VOIDmode, cc0_rtx,
- gen_rtx (COMPARE, DFmode, operands[1], reg1)));
-
- emit_jump_insn (gen_bge (label1));
-
- emit_insn (gen_fix_truncdfsi2 (operands[0], operands[1]));
- emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
- gen_rtx (LABEL_REF, VOIDmode, label2)));
- emit_barrier ();
-
- emit_label (label1);
- emit_move_insn (reg2, gen_rtx (MINUS, DFmode, operands[1], reg1));
- emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000));
-
- emit_insn (gen_fix_truncdfsi2 (operands[0], reg2));
- emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
-
- emit_label (label2);
-
- /* allow REG_NOTES to be set on last insn (labels don't have enough
- fields, and can't be used for REG_NOTES anyway). */
- emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
- DONE;
- }
- }")
-
- (define_expand "fixuns_truncsfsi2"
- [(set (match_operand:SI 0 "register_operand" "")
- (unsigned_fix:SI (match_operand:SF 1 "register_operand" "")))]
- ""
- "
- {
- rtx reg1 = gen_reg_rtx (SFmode);
- rtx reg2 = gen_reg_rtx (SFmode);
- rtx reg3 = gen_reg_rtx (SImode);
- rtx label1 = gen_label_rtx ();
- rtx label2 = gen_label_rtx ();
- REAL_VALUE_TYPE offset = REAL_VALUE_LDEXP (1.0, 31);
-
- if (reg1) /* turn off complaints about unreached code */
- {
- emit_move_insn (reg1, immed_real_const_1 (offset, SFmode));
- do_pending_stack_adjust ();
- emit_insn (gen_rtx (SET, VOIDmode, cc0_rtx,
- gen_rtx (COMPARE, SFmode, operands[1], reg1)));
-
- emit_jump_insn (gen_bge (label1));
-
- emit_insn (gen_fix_truncsfsi2 (operands[0], operands[1]));
- emit_jump_insn (gen_rtx (SET, VOIDmode, pc_rtx,
- gen_rtx (LABEL_REF, VOIDmode, label2)));
- emit_barrier ();
-
- emit_label (label1);
- emit_move_insn (reg2, gen_rtx (MINUS, SFmode, operands[1], reg1));
- emit_move_insn (reg3, gen_rtx (CONST_INT, VOIDmode, 0x80000000));
-
- emit_insn (gen_fix_truncsfsi2 (operands[0], reg2));
- emit_insn (gen_iorsi3 (operands[0], operands[0], reg3));
-
- emit_label (label2);
-
- /* allow REG_NOTES to be set on last insn (labels don't have enough
- fields, and can't be used for REG_NOTES anyway). */
- emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
- DONE;
- }
- }")
-
- ;;- Wild things used when
- ;;- unions make double and int
- ;;- overlap.
- ;;-
- ;;- This must be supported
- ;;- since corresponding code
- ;;- gets generated
-
- (define_insn ""
- [(set (subreg:DF (match_operand:DI 0 "register_operand" "=ry") 0)
- (match_operand:DF 1 "register_operand" "rf"))
- (clobber (match_operand 2 "register_operand" "rf"))]
- ""
- "mfc1\\t%0,%L1\;mfc1\\t%D0,%M1")
-
- (define_insn ""
- [(set (subreg:DF (match_operand:DI 0 "register_operand" "=ry") 0)
- (match_operand:DF 1 "register_operand" "rf"))]
- ""
- "mfc1\\t%0,%L1\;mfc1\\t%D0,%M1")
-
- (define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=rf")
- (subreg:DF (match_operand:DI 1 "register_operand" "ry") 0))
- (clobber (match_operand 2 "register_operand" "rf"))]
- ""
- "mfc1\\t%0,%L1\;mfc1\\t%D0,%M1")
-
- (define_insn ""
- [(set (match_operand:DF 0 "register_operand" "=rf")
- (subreg:DF (match_operand:DI 1 "register_operand" "ry") 0))]
- ""
- "mfc1\\t%0,%L1\;mfc1\\t%D0,%M1")
-
- ;;
- ;; ....................
- ;;
- ;; MOVES
- ;;
- ;; and
- ;;
- ;; LOADS AND STORES
- ;;
- ;; ....................
-
- (define_insn "movdi"
- [(set (match_operand:DI 0 "general_operand" "=r,*r,*m")
- (match_operand:DI 1 "general_operand" "r,*miF,*r"))]
- ""
- "*
- {
- extern rtx adj_offsettable_operand ();
- extern int offsettable_address_p ();
-
- if (which_alternative == 0)
- {
- /* Move REGISTER <- REGISTER */
- if (REGNO (operands[0]) != (REGNO (operands[1])+1))
- return \"move\\t%0,%1\\n\\tmove\\t%D0,%D1\";
- else
- return \"move\\t%D0,%D1\\n\\tmove\\t%0,%1\";
- }
-
- else if (which_alternative == 1)
- {
- if (GET_CODE (operands[1]) == MEM)
- {
- /* REGISTER <- MEMORY */
- if (offsettable_address_p (1, DImode, XEXP (operands[1], 0)))
- {
- operands[2] = adj_offsettable_operand (operands[1], 4);
- return \"lw\\t%0,%1\;lw\\t%D0,%2\";
- }
-
- else
- {
- operands[2] = gen_rtx (REG, Pmode, 1);
- return \".set\\tnoat\;la\\t%2,%1\;lw\\t%0,0(%2)\;lw\\t%D0,4(%2)\;set\\tat\";
- }
- }
-
- /* REGISTER <- small integer constant */
- else if (CONSTANT_P (operands[1]))
- {
- operands[2] = gen_rtx (CONST_INT, VOIDmode, INTVAL (operands[1]) >= 0 ? 0 : -1);
- return \"li\\t%M0,%2\;li\\t%L0,%1\";
- }
-
- /* Register <- large integer constant */
- else if (GET_CODE (operands[1]) == CONST_DOUBLE)
- {
- operands[2] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_LOW (operands[1]));
- operands[3] = gen_rtx (CONST_INT, VOIDmode, CONST_DOUBLE_HIGH (operands[1]));
- return \"li\\t%M0,%3\;li\\t%L0,%2\";
- }
- }
-
- else if (which_alternative == 2 && GET_CODE (operands[0]) == MEM)
- {
- /* Memory <- Register */
- if (offsettable_address_p (1, DImode, XEXP (operands[0], 0)))
- {
- operands[2] = adj_offsettable_operand (operands[0], 4);
- return \"sw\\t%1,%0\;sw\\t%D1,%2\";
- }
-
- else
- {
- operands[2] = gen_rtx (REG, Pmode, 1);
- return \".set\\tnoat\;la\\t%2,%0\;sw\\t%1,0(%2)\;sw\\t%D1,4(%2)\;set\\tat\";
- }
- }
-
- abort_with_insn (insn, \"impossible case in movdi\");
- return \"\";
- }")
-
- (define_insn "movsi"
- [(set (match_operand:SI 0 "general_operand" "=r,r,m,r,r,m,*r")
- (match_operand:SI 1 "general_operand" "r,m,r,i,J,J,*p"))]
- ""
- "*
- {
- enum rtx_code code0 = GET_CODE (operands[0]);
- enum rtx_code code1 = GET_CODE (operands[1]);
-
- if (code0 == REG && code1 == REG)
- return \"move\\t%0,%1\";
-
- else if (code0 == REG && code1 == MEM)
- return \"lw\\t%0,%1\";
-
- else if (code0 == MEM && code1 == REG)
- return \"sw\\t%1,%0\";
-
- else if (code0 == REG && code1 == CONST_INT)
- return \"li\\t%0,%1\";
-
- else if (code0 == MEM && code1 == CONST_INT && INTVAL (operands[1]) == 0)
- return \"sw\\t$0,%0\";
-
- else if (code0 == REG && CONSTANT_P (operands[1]))
- return \"la\\t%0,%a1\";
-
- else if (code0 == REG && code1 == PLUS
- && GET_CODE (XEXP (operands[1], 0)) == REG
- && GET_CODE (XEXP (operands[1], 1)) == CONST_INT)
- {
- operands[2] = XEXP (operands[1], 0);
- operands[3] = XEXP (operands[1], 1);
- return \"add%:\\t%0,%2,%3\";
- }
-
- abort_with_insn (insn, \"Bad movsi\");
- return 0;
- }")
-
- (define_insn "movhi"
- [(set (match_operand:HI 0 "general_operand" "=r,r,m,r,r,m")
- (match_operand:HI 1 "general_operand" "r,m,r,i,J,J"))]
- ""
- "*
- {
- enum rtx_code code0 = GET_CODE (operands[0]);
- enum rtx_code code1 = GET_CODE (operands[1]);
-
- if (code0 == REG && code1 == REG)
- return \"move\\t%0,%1\";
-
- else if (code0 == REG && code1 == MEM)
- return \"lh\\t%0,%1\";
-
- else if (code0 == MEM && code1 == REG)
- return \"sh\\t%1,%0\";
-
- else if (code0 == REG && code1 == CONST_INT)
- return \"li\\t%0,%1\";
-
- else if (code0 == MEM && code1 == CONST_INT && INTVAL (operands[1]) == 0)
- return \"sh\\t$0,%0\";
-
- else if (code0 == REG && CONSTANT_P (operands[1]))
- return \"la\\t%0,%a1\";
-
- else if (code0 == REG && code1 == PLUS
- && GET_CODE (XEXP (operands[1], 0)) == REG
- && GET_CODE (XEXP (operands[1], 1)) == CONST_INT)
- {
- operands[2] = XEXP (operands[1], 0);
- operands[3] = XEXP (operands[1], 1);
- return \"add%:\\t%0,%2,%3\";
- }
-
- abort_with_insn (insn, \"Bad movhi\");
- return 0;
- }")
-
- (define_insn "movqi"
- [(set (match_operand:QI 0 "general_operand" "=r,r,m,r,r,m")
- (match_operand:QI 1 "general_operand" "r,m,r,i,J,J"))]
- ""
- "*
- {
- enum rtx_code code0 = GET_CODE (operands[0]);
- enum rtx_code code1 = GET_CODE (operands[1]);
-
- if (code0 == REG && code1 == REG)
- return \"move\\t%0,%1\";
-
- else if (code0 == REG && code1 == MEM)
- return \"lb\\t%0,%1\";
-
- else if (code0 == MEM && code1 == REG)
- return \"sb\\t%1,%0\";
-
- else if (code0 == REG && code1 == CONST_INT)
- return \"li\\t%0,%1\";
-
- else if (code0 == MEM && code1 == CONST_INT && INTVAL (operands[1]) == 0)
- return \"sb\\t$0,%0\";
-
- else if (code0 == REG && CONSTANT_P (operands[1]))
- return \"la\\t%0,%a1\";
-
- else if (code0 == REG && code1 == PLUS
- && GET_CODE (XEXP (operands[1], 0)) == REG
- && GET_CODE (XEXP (operands[1], 1)) == CONST_INT)
- {
- operands[2] = XEXP (operands[1], 0);
- operands[3] = XEXP (operands[1], 1);
- return \"add%:\\t%0,%2,%3\";
- }
-
- abort_with_insn (insn, \"Bad movqi\");
- return 0;
- }")
-
- (define_insn "movsf"
- [(set (match_operand:SF 0 "general_operand" "=f,f,m,fy,*f,*y,*y,*m")
- (match_operand:SF 1 "general_operand" "f,m,f,F,*y,*f,*m,*y"))]
- ""
- "*
- {
- enum rtx_code code0 = GET_CODE (operands[0]);
- enum rtx_code code1 = GET_CODE (operands[1]);
-
- if (code0 == REG)
- {
- if (code1 == REG)
- {
- if (FP_REG_P (REGNO (operands[0])))
- {
- if (FP_REG_P (REGNO (operands[1])))
- return \"mov.s\\t%0,%1\";
- else
- return \"mtc1\\t%1,%0\\t\\t# Calling sequence trick\";
- }
-
- else if (FP_REG_P (REGNO (operands[1])))
- return \"mfc1\\t%0,%1\\t\\t# Calling sequence trick\";
-
- else
- return \"move\\t%0,%1\";
- }
-
- else if (code1 == CONST_DOUBLE)
- return \"li.s\\t%0,%1\";
-
- else if (code1 == MEM)
- return (GP_REG_P (REGNO (operands[0]))) ? \"lw\\t%0,%1\" : \"l.s\\t%0,%1\";
- }
-
- else if (code0 == MEM && code1 == REG)
- return (GP_REG_P (REGNO (operands[1]))) ? \"sw\\t%1,%0\" : \"s.s\\t%1,%0\";
-
- abort_with_insn (insn, \"Bad movsf\");
- return \"\";
- }")
-
-
- (define_insn "movdf"
- [(set (match_operand:DF 0 "general_operand" "=f,f,m,fy,*f,*y,&*y,*m")
- (match_operand:DF 1 "general_operand" "f,m,f,F,*y,*f,*m,*y"))]
- ""
- "*
- {
- extern rtx adj_offsettable_operand ();
- extern int offsettable_address_p ();
-
- enum rtx_code code0 = GET_CODE (operands[0]);
- enum rtx_code code1 = GET_CODE (operands[1]);
-
- if (code0 == REG)
- {
- if (code1 == REG)
- {
- if (FP_REG_P (REGNO (operands[0])))
- {
- if (FP_REG_P (REGNO (operands[1])))
- return \"mov.d\\t%0,%1\";
- else
- return \"mtc1\\t%L1,%0\\t\\t# Calling sequence trick\;mtc1\\t%M1,%D0\";
- }
-
- else if (FP_REG_P (REGNO (operands[1])))
- return \"mfc1\\t%L0,%1\\t\\t# Calling sequence trick\;mfc1\\t%M0,%D1\";
-
- else if (REGNO (operands[0]) != (REGNO (operands[1])+1))
- return \"move\\t%0,%1\\n\\tmove\\t%D0,%D1\";
-
- else
- return \"move\\t%D0,%D1\\n\\tmove\\t%0,%1\";
- }
-
- else if (code1 == CONST_DOUBLE)
- return \"li.d\\t%0,%1\";
-
- else if (code1 == MEM)
- {
- if (FP_REG_P (REGNO (operands[0])))
- return \"l.d\\t%0,%1\";
-
- else if (offsettable_address_p (1, DFmode, XEXP (operands[1], 0)))
- {
- operands[2] = adj_offsettable_operand (operands[1], 4);
- if (reg_mentioned_p (operands[0], operands[1]))
- return \"lw\\t%D0,%2\;lw\\t%0,%1\";
- else
- return \"lw\\t%0,%1\;lw\\t%D0,%2\";
- }
-
- else
- {
- operands[2] = gen_rtx (REG, Pmode, 1);
- return \".set\\tnoat\;la\\t%2,%1\;lw\\t%0,0(%2)\;lw\\t%D0,4(%2)\;set\\tat\";
- }
- }
- }
-
- else if (code0 == MEM && code1 == REG)
- {
- if (FP_REG_P (REGNO (operands[1])))
- return \"s.d\\t%1,%0\";
-
- else if (offsettable_address_p (1, DFmode, XEXP (operands[0], 0)))
- {
- operands[2] = adj_offsettable_operand (operands[0], 4);
- return \"sw\\t%1,%0\;sw\\t%D1,%2\";
- }
-
- else
- {
- operands[2] = gen_rtx (REG, Pmode, 1);
- return \".set\\tnoat\;la\\t%2,%0\;sw\\t%1,0(%2)\;sw\\t%D1,4(%2)\;set\\tat\";
- }
- }
-
- abort_with_insn (insn, \"Bad movdf\");
- return \"\";
- }")
-
-
- ;;
- ;; ....................
- ;;
- ;; OTHER ARITHMETIC AND SHIFT
- ;;
- ;; ....................
-
- (define_insn "ashlsi3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (ashift:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "arith_operand" "rI")))]
- ""
- "*
- {
- if (GET_CODE (operands[2]) == CONST_INT)
- operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);
-
- return \"sll\\t%0,%1,%2\";
- }")
-
- (define_insn "ashrsi3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "arith_operand" "rI")))]
- ""
- "*
- {
- if (GET_CODE (operands[2]) == CONST_INT)
- operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);
-
- return \"sra\\t%0,%1,%2\";
- }")
-
- (define_insn "lshrsi3"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
- (match_operand:SI 2 "arith_operand" "rI")))]
- ""
- "*
- {
- if (GET_CODE (operands[2]) == CONST_INT)
- operands[2] = gen_rtx (CONST_INT, VOIDmode, (XINT (operands[2], 0))& 0x1f);
-
- return \"srl\\t%0,%1,%2\";
- }")
-
- (define_insn "negsi2"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (neg:SI (match_operand:SI 1 "register_operand" "r")))]
- ""
- "sub%:\\t%0,$0,%1")
-
- (define_insn "negdf2"
- [(set (match_operand:DF 0 "register_operand" "=f")
- (neg:DF (match_operand:DF 1 "register_operand" "f")))]
- ""
- "neg.d\\t%0,%1")
-
- (define_insn "negsf2"
-
- [(set (match_operand:SF 0 "register_operand" "=f")
- (neg:SF (match_operand:SF 1 "register_operand" "f")))]
- ""
- "neg.s\\t%0,%1")
-
-
- (define_insn "one_cmplsi2"
- [(set (match_operand:SI 0 "register_operand" "=r")
- (not:SI (match_operand:SI 1 "register_operand" "r")))]
- ""
- "nor\\t%0,$0,%1")
-
- ;;
- ;; ....................
- ;;
- ;; COMPARISONS
- ;;
- ;; ....................
-
- ;;- Order is significant here
- ;;- because there are untyped
- ;;- comparisons generated by
- ;;- the optimizer
- ;;- (set (cc0)
- ;;- (compare (const_int 2)
- ;;- (const_int 1)))
-
- (define_insn "cmpsi"
- [(set (cc0)
- (compare (match_operand:SI 0 "register_operand" "r")
- (match_operand:SI 1 "arith_operand" "rI")))]
- ""
- "*
- compare_collect (SImode, operands[0], operands[1]);
- return \"\\t\\t\\t\\t# cmpsi\\t%0,%1\";
- ")
-
-
- (define_insn ""
- [(set (cc0)
- (match_operand:SI 0 "register_operand" "r"))]
- ""
- "*
- compare_collect (SImode, operands[0], gen_rtx (REG, SImode, 0));
- return \"\\t\\t\\t\\t# (set (cc0)\\t%0)\";
- ")
-
- ;; These patterns are hopelessly invalid, because
- ;; comparing subword values properly requires extending them.
-
- ;; (define_insn "cmphi"
- ;; [(set (cc0)
- ;; (compare (match_operand:HI 0 "register_operand" "r")
- ;; (match_operand:HI 1 "register_operand" "r")))]
- ;; ""
- ;; "*
- ;; compare_collect (HImode, operands[0], operands[1]);
- ;; return \" #\\tcmphi\\t%0,%1\";
- ;; ")
- ;;
- ;; (define_insn "cmpqi"
- ;; [(set (cc0)
- ;; (compare (match_operand:QI 0 "register_operand" "r")
- ;; (match_operand:QI 1 "register_operand" "r")))]
- ;; ""
- ;; "*
- ;; compare_collect (QImode, operands[0], operands[1]);
- ;; return \" #\\tcmpqi\\t%0,%1\";
- ;; ")
- ;;
- ;; (define_insn ""
- ;; [(set (cc0)
- ;; (match_operand:QI 0 "register_operand" "r"))]
- ;; ""
- ;; "*
- ;; compare_collect (QImode, operands[0], gen_rtx (REG, QImode, 0));
- ;; return \" #\\t (set (cc0)\\t%0)\";
- ;; ")
- ;;
- ;; (define_insn ""
- ;; [(set (cc0)
- ;; (match_operand:HI 0 "register_operand" "r"))]
- ;; ""
- ;; "*
- ;; compare_collect (HImode, operands[0], gen_rtx (REG, HImode, 0));
- ;; return \" #\\t (set (cc0)\\t%0)\";
- ;; ")
-
- (define_insn "cmpdf"
- [(set (cc0)
- (compare (match_operand:DF 0 "register_operand" "f")
- (match_operand:DF 1 "register_operand" "f")))]
- ""
- "*
- compare_collect (DFmode, operands[0], operands[1]);
- return \" #\\t\\t\\t\\tcmpdf\\t%0,%1\" ;
- ")
-
- (define_insn "cmpsf"
- [(set (cc0)
- (compare (match_operand:SF 0 "register_operand" "f")
- (match_operand:SF 1 "register_operand" "f")))]
- ""
- "*
- compare_collect (SFmode, operands[0], operands[1]);
- return \"\\t\\t\\t\\t# cmpsf\\t%0,%1\" ;
- ")
-
- ;;
- ;; ....................
- ;;
- ;; BRANCHES
- ;;
- ;; ....................
-
- (define_insn "jump"
- [(set (pc)
- (label_ref (match_operand 0 "" "")))]
- ""
- "*
- {
- if (GET_CODE (operands[0]) == REG)
- return \"j\\t%0\";
- else
- return \"j\\t%l0\";
- }")
-
-
- (define_insn "tablejump"
- [(set (pc)
- (match_operand:SI 0 "register_operand" "r"))
- (use (label_ref (match_operand 1 "" "")))]
- ""
- "j\\t%0")
-
-
- (define_insn "beq"
- [(set (pc)
- (if_then_else (eq (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "*
- {
- rtx br_ops[3];
- enum machine_mode mode;
- compare_restore (br_ops, &mode, insn);
- br_ops[2] = operands[0];
- if (mode == DFmode)
- {
- output_asm_insn (\"c.eq.d\\t%0,%1\\t\\t# beq\", br_ops);
- output_asm_insn (\"bc1t\\t%2\\t\\t# beq\", br_ops);
- }
- else if (mode == SFmode)
- {
- output_asm_insn (\"c.eq.s\\t%0,%1\\t\\t# beq\", br_ops);
- output_asm_insn (\"bc1t\\t%2\\t\\t# beq\", br_ops);
- }
- else
- {
- output_asm_insn (\"beq\\t%0,%1,%2\\t\\t# beq\", br_ops);
- }
- return \"\";
- }
- ")
-
- (define_insn "bne"
- [(set (pc)
- (if_then_else (ne (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "*
- {
- rtx br_ops[3];
- enum machine_mode mode;
- compare_restore (br_ops, &mode, insn);
- br_ops[2] = operands[0];
- if (mode == DFmode)
- {
- output_asm_insn (\"c.eq.d\\t%0,%1\\t\\t# bne\", br_ops);
- output_asm_insn (\"bc1f\\t%2\\t\\t# bne\", br_ops);
- }
- else if (mode == SFmode)
- {
- output_asm_insn (\"c.eq.s\\t%0,%1\\t\\t# bne\", br_ops);
- output_asm_insn (\"bc1f\\t%2\\t\\t# bne\", br_ops);
- }
- else
- {
- output_asm_insn (\"bne\\t%0,%1,%2\\t\\t# bne\", br_ops);
- }
- return \"\";
- }
-
- ")
-
- (define_insn "bgt"
- [(set (pc)
- (if_then_else (gt (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "*
- {
- rtx br_ops[3];
- enum machine_mode mode;
- compare_restore (br_ops, &mode, insn);
- br_ops[2] = operands[0];
- if (mode == DFmode)
- {
- output_asm_insn (\"c.le.d\\t%0,%1\\t\\t# bgt branch %0 > %1\", br_ops);
- output_asm_insn (\"bc1f\\t%2\\t\\t# bgt\", br_ops);
- }
- else if (mode == SFmode)
- {
- output_asm_insn (\"c.le.s\\t%0,%1\\t\\t# bgt branch %0 > %1\", br_ops);
- output_asm_insn (\"bc1f\\t%2\\t\\t# bgt\", br_ops);
- }
- else
- {
- output_asm_insn (\"bgt\\t%0,%1,%2\\t\\t# bgt\", br_ops);
- }
- return \"\";
- }
-
- ")
-
- (define_insn "blt"
- [(set (pc)
- (if_then_else (lt (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "*
- {
- rtx br_ops[3];
- enum machine_mode mode;
- compare_restore (br_ops, &mode, insn);
- br_ops[2] = operands[0];
- if (mode == DFmode)
- {
- output_asm_insn (\"c.lt.d\\t%0,%1\\t\\t# blt\", br_ops);
- output_asm_insn (\"bc1t\\t%2\\t\\t# blt\", br_ops);
- }
- else if (mode == SFmode)
- {
- output_asm_insn (\"c.lt.s\\t%0,%1\\t\\t# blt\", br_ops);
- output_asm_insn (\"bc1t\\t%2\\t\\t# blt\", br_ops);
- }
- else
- {
- output_asm_insn (\"blt\\t%0,%1,%2\\t\\t# blt\", br_ops);
- }
- return \" #\\tblt\\t%l0\\t\\t# blt\";
- }
- ")
-
- (define_insn "bgtu"
- [(set (pc)
- (if_then_else (gtu (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "*
- {
- rtx br_ops[3];
- enum machine_mode mode;
- compare_restore (br_ops, &mode, insn);
- br_ops[2] = operands[0];
- if (mode == DFmode)
- {
- output_asm_insn (\"c.le.d\\t%0,%1\\t\\t# bgtu\", br_ops);
- output_asm_insn (\"bc1f\\t%2\\t\\t# bgtu\", br_ops);
- }
- else if (mode == SFmode)
- {
- output_asm_insn (\"c.le.s\\t%0,%1\\t\\t# bgtu\", br_ops);
- output_asm_insn (\"bc1f\\t%2\\t\\t# bgtu\", br_ops);
- }
- else
- {
- output_asm_insn (\"bgtu\\t%0,%1,%2\\t\\t# bgtu\", br_ops);
- }
- return \" #\\tbgtu\\t%l0\\t\\t# bgtu\";
- }
- ")
-
- (define_insn "bltu"
- [(set (pc)
- (if_then_else (ltu (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "*
- {
- rtx br_ops[3];
- enum machine_mode mode;
- compare_restore (br_ops, &mode, insn);
- br_ops[2] = operands[0];
- if (mode == DFmode)
- {
- output_asm_insn (\"c.lt.d\\t%0,%1\\t\\t# bltu\", br_ops);
- output_asm_insn (\"bc1t\\t%2\\t\\t# bltu\", br_ops);
- }
- else if (mode == SFmode)
- {
- output_asm_insn (\"c.lt.s\\t%0,%1\\t\\t# bltu\", br_ops);
- output_asm_insn (\"bc1t\\t%2\\t\\t# bltu\", br_ops);
- }
- else
- {
- output_asm_insn (\"bltu\\t%0,%1,%2\\t\\t# bltu\", br_ops);
- }
- return \"\";
- }
- ")
-
- (define_insn "bge"
- [(set (pc)
- (if_then_else (ge (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "*
- {
- rtx br_ops[3];
- enum machine_mode mode;
- compare_restore (br_ops, &mode, insn);
- br_ops[2] = operands[0];
- if (mode == DFmode)
- {
- output_asm_insn (\"c.lt.d\\t%0,%1\\t\\t# bge\", br_ops);
- output_asm_insn (\"bc1f\\t%2\\t\\t# bge\", br_ops);
- }
- else if (mode == SFmode)
- {
- output_asm_insn (\"c.lt.s\\t%0,%1\\t\\t# bge\", br_ops);
- output_asm_insn (\"bc1f\\t%2\\t\\t# bge\", br_ops);
- }
- else
- {
- output_asm_insn (\"bge\\t%0,%1,%2\\t\\t# bge\", br_ops);
- }
- return \"\";
- }
- ")
-
- (define_insn "bgeu"
- [(set (pc)
- (if_then_else (geu (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "*
- {
- rtx br_ops[3];
- enum machine_mode mode;
- compare_restore (br_ops, &mode, insn);
- br_ops[2] = operands[0];
- if (mode == DFmode)
- {
- output_asm_insn (\"c.lt.d\\t%0,%1\\t\\t# bgeu\", br_ops);
- output_asm_insn (\"bc1f\\t%2\\t\\t# bgeu\", br_ops);
- }
- else if (mode == SFmode)
- {
- output_asm_insn (\"c.lt.s\\t%0,%1\\t\\t# bgeu\", br_ops);
- output_asm_insn (\"bc1f\\t%2\\t\\t# bgeu\", br_ops);
- }
- else
- {
- output_asm_insn (\"bgeu\\t%0,%1,%2\\t\\t# bgeu\", br_ops);
- }
- return \"\";
- }
- ")
-
- (define_insn "ble"
- [(set (pc)
- (if_then_else (le (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "*
- {
- rtx br_ops[3];
- enum machine_mode mode;
- compare_restore (br_ops, &mode, insn);
- br_ops[2] = operands[0];
- if (mode == DFmode)
- {
- output_asm_insn (\"c.le.d\\t%0,%1\\t\\t# ble\", br_ops);
- output_asm_insn (\"bc1t\\t%2\\t\\t# ble\", br_ops);
- }
- else if (mode == SFmode)
- {
- output_asm_insn (\"c.le.s\\t%0,%1\\t\\t# ble\", br_ops);
- output_asm_insn (\"bc1t\\t%2\\t\\t# ble\", br_ops);
- }
- else
- {
- output_asm_insn (\"ble\\t%0,%1,%2\\t\\t# ble\", br_ops);
- }
- return \"\";
- }
- ")
-
- (define_insn "bleu"
- [(set (pc)
- (if_then_else (leu (cc0)
- (const_int 0))
- (label_ref (match_operand 0 "" ""))
- (pc)))]
- ""
- "*
- {
- rtx br_ops[3];
- enum machine_mode mode;
- compare_restore (br_ops, &mode, insn);
- br_ops[2] = operands[0];
- if (mode == DFmode)
- {
- output_asm_insn (\"c.le.d\\t%0,%1\\t\\t# ble\", br_ops);
- output_asm_insn (\"bc1t\\t%2\\t\\t# ble\", br_ops);
- }
- else if (mode == SFmode)
- {
- output_asm_insn (\"c.le.s\\t%0,%1\\t\\t# ble\", br_ops);
- output_asm_insn (\"bc1t\\t%2\\t\\t# ble\", br_ops);
- }
- else
- {
- output_asm_insn (\"bleu\\t%0,%1,%2\\t\\t# bleu\", br_ops);
- }
- return \" #\\tbleu\\t%l0\\t\\t# bleu\";
- }
- ")
-
- (define_insn ""
- [(set (pc)
- (if_then_else (ne (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "*
- {
- rtx br_ops[3];
- enum machine_mode mode;
- compare_restore (br_ops, &mode, insn);
- br_ops[2] = operands[0];
- if (mode == DFmode)
- {
- output_asm_insn (\"c.eq.d\\t%0,%1\\t\\t# beq\", br_ops);
- output_asm_insn (\"bc1t\\t%2\\t\\t# beq\", br_ops);
- }
- else if (mode == SFmode)
- {
- output_asm_insn (\"c.eq.s\\t%0,%1\\t\\t# beq\", br_ops);
- output_asm_insn (\"bc1t\\t%2\\t\\t# beq\", br_ops);
- }
- else
- {
- output_asm_insn (\"beq\\t%0,%1,%2\\t\\t# beq Inv.\", br_ops);
- }
- return \"\";
- }
- ")
-
- (define_insn ""
- [(set (pc)
- (if_then_else (eq (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "*
- {
- rtx br_ops[3];
- enum machine_mode mode;
- compare_restore (br_ops, &mode, insn);
- br_ops[2] = operands[0];
- if (mode == DFmode)
- {
- output_asm_insn (\"c.eq.d\\t%0,%1\\t\\t# bne\", br_ops);
- output_asm_insn (\"bc1f\\t%2\\t\\t# bne\", br_ops);
- }
- else if (mode == SFmode)
- {
- output_asm_insn (\"c.eq.s\\t%0,%1\\t\\t# bne\", br_ops);
- output_asm_insn (\"bc1f\\t%2\\t\\t# beq\", br_ops);
- }
- else
- {
- output_asm_insn (\"bne\\t%0,%1,%2\\t\\t# bne Inv.\", br_ops);
- }
- return \"\";
- }
-
- ")
-
- (define_insn ""
- [(set (pc)
- (if_then_else (le (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "*
- {
- rtx br_ops[3];
- enum machine_mode mode;
- compare_restore (br_ops, &mode, insn);
- br_ops[2] = operands[0];
- if (mode == DFmode)
- {
- output_asm_insn (\"c.le.d\\t%0,%1\\t\\t# bgt\", br_ops);
- output_asm_insn (\"bc1f\\t%2\\t\\t# beq\", br_ops);
- }
- else if (mode == SFmode)
- {
- output_asm_insn (\"c.le.s\\t%0,%1\\t\\t# bgt\", br_ops);
- output_asm_insn (\"bc1f\\t%2\\t\\t# beq\", br_ops);
- }
- else
- {
- output_asm_insn (\"bgt\\t%0,%1,%2\\t\\t# bgt Inv.\", br_ops);
- }
- return \"\";
- }
- ")
-
- (define_insn ""
- [(set (pc)
- (if_then_else (leu (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "*
- {
- rtx br_ops[3];
- enum machine_mode mode;
- compare_restore (br_ops, &mode, insn);
- br_ops[2] = operands[0];
- if (mode == DFmode)
- {
- output_asm_insn (\"c.le.d\\t%0,%1\\t\\t# bgt\", br_ops);
- output_asm_insn (\"bc1f\\t%2\\t\\t# beq\", br_ops);
- }
- else if (mode == SFmode)
- {
- output_asm_insn (\"c.le.s\\t%0,%1\\t\\t# bgt\", br_ops);
- output_asm_insn (\"bc1f\\t%2\\t\\t# beq\", br_ops);
- }
- else
- {
- output_asm_insn (\"bgtu\\t%0,%1,%2\\t\\t# bgtu Inv.\", br_ops);
- }
- return \" #\\tbgtu\\t%l0\\t\\t# bgtu\";
- }
- ")
-
- (define_insn ""
- [(set (pc)
- (if_then_else (ge (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "*
- {
- rtx br_ops[3];
- enum machine_mode mode;
- compare_restore (br_ops, &mode, insn);
- br_ops[2] = operands[0];
- if (mode == DFmode)
- {
- output_asm_insn (\"c.lt.d\\t%0,%1\\t\\t# blt\", br_ops);
- output_asm_insn (\"bc1t\\t%2\\t\\t# beq\", br_ops);
- }
- else if (mode == SFmode)
- {
- output_asm_insn (\"c.lt.s\\t%0,%1\\t\\t# blt\", br_ops);
- output_asm_insn (\"bc1t\\t%2\\t\\t# beq\", br_ops);
- }
- else
- {
- output_asm_insn (\"blt\\t%0,%1,%2\\t\\t# blt Inv.\", br_ops);
- }
- return \"\";
- }
- ")
-
- (define_insn ""
- [(set (pc)
- (if_then_else (geu (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "*
- {
- rtx br_ops[3];
- enum machine_mode mode;
- compare_restore (br_ops, &mode, insn);
- br_ops[2] = operands[0];
- if (mode == DFmode)
- {
- output_asm_insn (\"c.lt.d\\t%0,%1\\t\\t# bltu\", br_ops);
- output_asm_insn (\"bc1t\\t%2\\t\\t# bltu\", br_ops);
- }
- else if (mode == SFmode)
- {
- output_asm_insn (\"c.lt.s\\t%0,%1\\t\\t# bltu\", br_ops);
- output_asm_insn (\"bc1t\\t%2\\t\\t# bltu\", br_ops);
- }
- else
- {
- output_asm_insn (\"bltu\\t%0,%1,%2\\t\\t# bltu Inv.\", br_ops);
- }
- return \" #\\tbltu\\t%l0\\t\\t# bltu\";
- }
- ")
-
- (define_insn ""
- [(set (pc)
- (if_then_else (lt (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "*
- {
- rtx br_ops[3];
- enum machine_mode mode;
- compare_restore (br_ops, &mode, insn);
- br_ops[2] = operands[0];
- if (mode == DFmode)
- {
- output_asm_insn (\"c.lt.d\\t%0,%1\\t\\t# bge\", br_ops);
- output_asm_insn (\"bc1f\\t%2\\t\\t# bge (DF) Inv.\", br_ops);
- }
- else if (mode == SFmode)
- {
- output_asm_insn (\"c.lt.s\\t%0,%1\\t\\t# bge\", br_ops);
- output_asm_insn (\"bc1f\\t%2\\t\\t# bge (SF) Inv.\", br_ops);
- }
- else
- {
- output_asm_insn (\"bge\\t%0,%1,%2\\t\\t# bge Inv.\", br_ops);
- }
- return \"\";
- }
- ")
-
- (define_insn ""
- [(set (pc)
- (if_then_else (ltu (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "*
- {
- rtx br_ops[3];
- enum machine_mode mode;
- compare_restore (br_ops, &mode, insn);
- br_ops[2] = operands[0];
- if (mode == DFmode)
- {
- output_asm_insn (\"c.lt.d\\t%0,%1\\t\\t# bge\", br_ops);
- output_asm_insn (\"bc1f\\t%2\\t\\t# bgeu (DF) Inv.\", br_ops);
- }
- else if (mode == SFmode)
- {
- output_asm_insn (\"c.lt.s\\t%0,%1\\t\\t# bge\", br_ops);
- output_asm_insn (\"bc1f\\t%2\\t\\t# bgeu (SF )Inv.\", br_ops);
- }
- else
- {
- output_asm_insn (\"bgeu\\t%0,%1,%2\\t\\t# bgeu Inv.\", br_ops);
- }
- return \" #\\tbgeu\\t%l0\\t\\t# bgeu\";
- }
- ")
-
- (define_insn ""
- [(set (pc)
- (if_then_else (gt (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "*
- {
- rtx br_ops[3];
- enum machine_mode mode;
- compare_restore (br_ops, &mode, insn);
- br_ops[2] = operands[0];
- if (mode == DFmode)
- {
- output_asm_insn (\"c.le.d\\t%0,%1\\t\\t# ble\", br_ops);
- output_asm_insn (\"bc1t\\t%2\\t\\t# ble\", br_ops);
- }
- else if (mode == SFmode)
- {
- output_asm_insn (\"c.le.s\\t%0,%1\\t\\t# ble\", br_ops);
- output_asm_insn (\"bc1t\\t%2\\t\\t# ble\", br_ops);
- }
- else
- {
- output_asm_insn (\"ble\\t%0,%1,%2\\t\\t# ble Inv.\", br_ops);
- }
- return \"\";
- }
- ")
-
- (define_insn ""
- [(set (pc)
- (if_then_else (gtu (cc0)
- (const_int 0))
- (pc)
- (label_ref (match_operand 0 "" ""))))]
- ""
- "*
- {
- rtx br_ops[3];
- enum machine_mode mode;
- compare_restore (br_ops, &mode, insn);
- br_ops[2] = operands[0];
- if (mode == DFmode)
- {
- output_asm_insn (\"c.le.d\\t%0,%1\\t\\t# bleu\", br_ops);
- output_asm_insn (\"bc1t\\t%2\\t\\t# bleu\", br_ops);
- }
- else if (mode == SFmode)
- {
- output_asm_insn (\"c.le.s\\t%0,%1\\t\\t# bleu\", br_ops);
- output_asm_insn (\"bc1t\\t%2\\t\\t# bleu\", br_ops);
- }
- else
- {
- output_asm_insn (\"bleu\\t%0,%1,%2\\t\\t# bleu Inv.\", br_ops);
- }
- return \"\";
- }
- ")
-
- ;;
- ;; ....................
- ;;
- ;; LINKAGE
- ;;
- ;; ....................
-
- (define_insn "call"
- [(call (match_operand 0 "memory_operand" "m")
- (match_operand 1 "" "i"))
- (clobber (reg:SI 31))]
- ""
- "*
- {
- register rtx target = XEXP (operands[0], 0);
-
- if (GET_CODE (target) == SYMBOL_REF)
- return \"jal\\t%0\";
-
- else
- {
- operands[0] = target;
- return \"jal\\t$31,%0\";
- }
- }")
-
-
- (define_insn "call_value"
- [(set (match_operand 0 "" "=rf")
- (call (match_operand 1 "memory_operand" "m")
- (match_operand 2 "" "i")))
- (clobber (reg:SI 31))]
- ""
- "*
- {
- register rtx target = XEXP (operands[1], 0);
-
- if (GET_CODE (target) == SYMBOL_REF)
- return \"jal\\t%1\";
-
- else
- {
- operands[1] = target;
- return \"jal\\t$31,%1\";
- }
- }")
-
- (define_insn "nop"
- [(const_int 0)]
- ""
- ".set\\tnoreorder\;nop\;.set\\treorder")
-
- (define_insn "probe"
- [(mem:SI (reg:SI 29))]
- ""
- "*
- {
- operands[0] = gen_rtx (REG, SImode, 1);
- operands[1] = stack_pointer_rtx;
- return \".set\\tnoat\;lw\\t%0,0(%1)\\t\\t# stack probe\;.set\\tat\";
- }")
-
- ;;
- ;;- 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:
-