;;- Machine description for GNU compiler
;;- MIL-STD-1750A version.
-;; Copyright (C) 1994, 1995 Free Software Foundation, Inc.
-;; Contributed by O.M.Kellogg, DASA (kellogg@space.otn.dasa.de).
+;; Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999,
+;; 2000 Free Software Foundation, Inc.
+;; Contributed by O.M.Kellogg, DASA (oliver.kellogg@space.otn.dasa.de).
;; 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)
+;; 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,
[(set (match_operand:HI 0 "push_operand" "=<")
(match_operand:HI 1 "general_operand" "r"))]
""
- "*
- {
- rtx new_operands[2];
- new_operands[0] = operands[1];
- new_operands[1] = gen_rtx(CONST_INT,VOIDmode,REGNO(operands[1])+1);
- } ")
+ "pshm r%1,r%d1")
(define_insn ""
[(set (match_operand:HF 0 "push_operand" "=<")
(match_operand:HF 1 "general_operand" "r"))]
""
- "*
- {
- rtx new_operands[2];
- new_operands[0] = operands[1];
- new_operands[1] = gen_rtx(CONST_INT,VOIDmode,REGNO(operands[1])+1);
- output_asm_insn(\"pshm r%0,r%1\",new_operands);
- return \"\;\";
- } ")
+ "pshm r%1,r%d1")
(define_insn ""
[(set (match_operand:TQF 0 "push_operand" "=<")
(match_operand:TQF 1 "general_operand" "r"))]
""
- "*
- {
- rtx new_operands[2];
- new_operands[0] = operands[1];
- new_operands[1] = gen_rtx(CONST_INT,VOIDmode,REGNO(operands[1])+2);
- output_asm_insn(\"pshm r%0,r%1\",new_operands);
- return \"\;\";
- } ")
+ "pshm r%1,r%t1")
;; stackpop
(define_insn ""
[(set (match_operand:HI 0 "general_operand" "=r")
(match_operand:HI 1 "push_operand" ">"))]
""
- "*
- {
- rtx new_operands[2];
- new_operands[0] = operands[0];
- new_operands[1] = gen_rtx(CONST_INT,VOIDmode,REGNO(operands[0])+1);
- output_asm_insn(\"popm r%0,r%1\",new_operands);
- return \"\;\";
- } ")
+ "popm r%1,r%d1")
(define_insn ""
[(set (match_operand:HF 0 "general_operand" "=r")
(match_operand:HF 1 "push_operand" ">"))]
""
- "*
- {
- rtx new_operands[2];
- new_operands[0] = operands[0];
- new_operands[1] = gen_rtx(CONST_INT,VOIDmode,REGNO(operands[0])+1);
- output_asm_insn(\"popm r%0,r%1\",new_operands);
- return \"\;\";
- } ")
-
+ "popm r%1,r%d1")
+
(define_insn ""
[(set (match_operand:TQF 0 "general_operand" "=r")
(match_operand:TQF 1 "push_operand" ">"))]
""
- "*
- {
- rtx new_operands[2];
- new_operands[0] = operands[0];
- new_operands[1] = gen_rtx(CONST_INT,VOIDmode,REGNO(operands[0])+2);
- output_asm_insn(\"popm r%0,r%1\",new_operands);
- return \"\;\";
- } ")
+ "popm r%1,r%t1")
-;; Test operations. These shouldn't really occur for 1750:
-;; all important instructions set the cc's (see NOTICE_UPDATE_CC)
+
+;; Test operations.
(define_insn "tstqi"
[(set (cc0)
""
"dlr r%0,r%0 ; from tsthi")
+; With 1750A floats, testing the most significant word suffices.
+
(define_insn "tsthf"
[(set (cc0)
(match_operand:HF 0 "register_operand" "r"))]
""
- "dlr r%0,r%0 ; from tsthf")
+ "lr r%0,r%0 ; tsthf")
-;; This one is happy with "roughly zero" :-) (should be improved)
(define_insn "tsttqf"
[(set (cc0)
(match_operand:TQF 0 "register_operand" "r"))]
""
- "dlr r%0,r%0 ; from tsttqf")
+ "lr r%0,r%0 ; tsttqf")
;; block move.
-; there is a problem with this insn in gcc-2.2.3
-; (clobber (match_dup 2)) does not prevent use of this operand later
-;
(define_insn "movstrqi"
- [(set (mem:BLK (match_operand:QI 0 "register_operand" "r"))
- (mem:BLK (match_operand:QI 1 "register_operand" "r")))
- (use (match_operand:QI 2 "register_operand" "r"))
- (use (match_operand:QI 3 "immediate_operand" ""))
+ [(set (match_operand:BLK 0 "mov_memory_operand" "=m")
+ (match_operand:BLK 1 "mov_memory_operand" "m"))
+ (use (match_operand:QI 2 "general_operand" "r"))
+ (match_operand 3 "" "")
(clobber (match_dup 0))
(clobber (match_dup 1))
(clobber (match_dup 2))]
""
- "* return (char *)movcnt_regno_adjust(operands); ")
+ "*
+ {
+ rtx regops[3];
+
+ regops[0] = XEXP (operands[0], 0);
+ regops[1] = XEXP (operands[1], 0);
+ regops[2] = operands[2];
+
+ return movcnt_regno_adjust (regops);
+ } ")
;; compare instructions.
return \"ucr.m %0,%1\";
case 4:
return \"uc.m %0,%1\";
+ default:
+ abort();
}
else
switch (which_alternative)
return \"cr r%0,r%1\";
case 4:
return \"c r%0,%1\";
+ default:
+ abort();
}
} ")
(compare (match_operand:HI 0 "general_operand" "r,r")
(match_operand:HI 1 "general_operand" "r,m")))]
""
- "@
- dcr r%0,r%1
- dc r%0,%1 ")
+ "*
+ {
+ if (next_cc_user_is_unsigned (insn))
+ {
+ if (which_alternative == 0)
+ return \"ducr.m %0,%1\";
+ return \"duc.m %0,%1\";
+ }
+ else
+ {
+ if (which_alternative == 0)
+ return \"dcr r%0,r%1\";
+ return \"dc r%0,%1\";
+ }
+ } ")
(define_insn "cmphf"
[(set (cc0)
(define_insn "trunchiqi2"
[(set (match_operand:QI 0 "register_operand" "=r")
- (truncate:QI
- (match_operand:HI 1 "register_operand" "r")))]
+ (truncate:QI (match_operand:HI 1 "register_operand" "r")))]
""
- "*
- {
- REGNO(operands[1]) += 1;
- return \"lr r%0,r%1 ;trunchiqi2\";
- } ")
+ "lr r%0,r%d1")
-;; zero extension instructions
-(define_insn "zero_extendqihi2"
- [(set (match_operand:HI 0 "register_operand" "=r,r,r")
- (zero_extend:HI (match_operand:QI 1 "general_operand" "r,m,i")))]
- ""
- "*
- {
- output_asm_insn(\"xorr r%0,r%0 ;zero_extendqihi2\",operands);
- REGNO(operands[0]) += 1;
- switch (which_alternative)
- {
- case 0:
- return \"lr r%0,r%1\";
- case 1:
- return \"l r%0,%1\";
- case 2:
- return \"lim r%0,%1\";
- }
- } ")
+;; zero extension instructions: not defined, GCC can synthesize
;; sign extension instructions
(define_insn "extendqihi2"
- [(set (match_operand:HI 0 "register_operand" "=r,r,r")
- (sign_extend:HI (match_operand:QI 1 "general_operand" "r,m,i")) )]
+ [(set (match_operand:HI 0 "register_operand" "=r,r")
+ (sign_extend:HI (match_operand:QI 1 "general_operand" "r,m")) )]
""
- "@
- lr r%0,r%1 ;extendqihi2\;dsra r%0,16
- l r%0,%1 ;extendqihi2\;dsra r%0,16
- lim r%0,%1 ;extendqihi2\;dsra r%0,16 ")
+ "*
+ if (which_alternative == 0)
+ {
+ if (REGNO (operands [0]) != REGNO (operands [1]))
+ output_asm_insn (\"lr r%0,r%1\", operands);
+ }
+ else
+ output_asm_insn (\"l r%0,%1\", operands);
+ return \"dsra r%0,16 ;extendqihi2\";
+ ")
;; Conversions between float and double.
; 1750 HF-to-TQF extend: just append 16 bits (least signif.) with all bits zero
(define_insn "extendhftqf2"
[(set (match_operand:TQF 0 "register_operand" "=r,r")
- (float_extend:TQF
- (match_operand:HF 1 "general_operand" "r,m")))]
+ (float_extend:TQF (match_operand:HF 1 "general_operand" "r,m")))]
""
"*
+ output_asm_insn(\"xorr r%t0,r%t0 ;extendhftqf2\", operands);
+ if (which_alternative == 0)
{
- REGNO(operands[0]) += 2;
- output_asm_insn(\"xorr r%0,r%0 ;extendhftqf2\",operands);
- REGNO(operands[0]) -= 2;
- if (which_alternative == 0)
+ if (REGNO (operands[1]) != REGNO (operands[0]))
return \"dlr r%0,r%1\";
else
- return \"dl r%0,%1\";
- } ")
+ return \";\";
+ }
+ else
+ return \"dl r%0,%1\";
+ ")
; 1750 TQF-to-HF truncate is a no-op: just leave away the least signif. 16 bits
(define_insn "trunctqfhf2"
;; 16-bit moves
+; memory indirect to reg
+(define_insn ""
+ [(set (match_operand:QI 0 "register_operand" "=r")
+ (mem:QI (match_operand 1 "memory_operand" "m")))]
+ ""
+ "li r%0,%1")
+
+; reg/const to memory indirect
+(define_insn ""
+ [(set (mem:QI (match_operand 0 "memory_operand" "=m,m"))
+ (match_operand:QI 1 "nonmemory_operand" "r,K"))]
+ ""
+ "@
+ sti r%1,%0
+ stci %1,%0")
+
+; general case
(define_insn "movqi"
- [(set (match_operand:QI 0 "general_operand" "=r,r,r,r,r,r,r,m,m")
- (match_operand:QI 1 "general_operand" "O,I,J,M,i,r,m,r,K"))]
+ [(set (match_operand:QI 0 "general_operand" "=r,r,r,r,r,r,m,m")
+ (match_operand:QI 1 "general_operand" "O,I,J,i,r,m,r,K"))]
""
"@
xorr r%0,r%0
lisp r%0,%1
lisn r%0,%J1
- lim r%0,%1 ; 'M' constraint
- lim r%0,%1 ; 'i' constraint
+ lim r%0,%1
lr r%0,r%1
l r%0,%1
st r%1,%0
;; 32-bit moves
-;; Set HIreg to constant
+; memory indirect to reg
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
- (match_operand 1 "immediate_operand" "i"))]
+ (mem:HI (match_operand 1 "memory_operand" "m")))]
""
- "*
- if (GET_CODE(operands[1]) == CONST_INT)
- {
- int val = INTVAL(operands[1]);
- if (val >= 0)
- {
- if (val <= 65535)
- {
- output_asm_insn(\"xorr r%0,r%0 ;movhi cst->reg\",operands);
- operands[0] = gen_rtx(REG,QImode,REGNO(operands[0]) + 1);
- if (val == 0)
- return \"xorr r%0,r%0\";
- else if (val <= 16)
- return \"lisp r%0,%1\";
- else
- return \"lim r%0,%1\";
- }
- }
- else if (val >= -16)
- return \"lisn r%0,%J1\;dsra r%0,16 ;movhi cst\";
- INTVAL(operands[1]) >>= 16;
- output_asm_insn(\"lim r%0,%1 ;movhi cst->reg\",operands);
- REGNO(operands[0]) += 1;
- INTVAL(operands[1]) = val & 0xFFFF;
- return \"lim r%0,%1\";
- }
- return \"lim r%0,%1\;dsra r%0,16 ;movhi cst\";
- ")
+ "dli r%0,%1")
-(define_insn "movhi"
- [(set (match_operand:HI 0 "general_operand" "=r,r,m")
- (match_operand:HI 1 "general_operand" "r,m,r"))]
+; reg to memory indirect
+(define_insn ""
+ [(set (mem:HI (match_operand 0 "memory_operand" "=m"))
+ (match_operand:HI 1 "register_operand" "r"))]
""
- "@
- dlr r%0,r%1
- dl r%0,%1
- dst r%1,%0 ")
+ "dsti r%1,%0")
+; general case
+(define_insn ""
+ [(set (match_operand:HI 0 "general_operand" "=r,r,r,r,r,m,m")
+ (match_operand:HI 1 "general_operand" "O,I,J,r,m,r,K"))]
+ ""
+ "@
+ xorr r%0,r%0\;xorr r%d0,r%d0
+ xorr r%0,r%0\;lisp r%d0,%1
+ lisn r%0,1 \;lisn r%d0,%J1
+ dlr r%0,r%1
+ dl r%0,%1
+ dst r%1,%0
+ stc 0,%0 \;stc %1,%A0 ")
+
+(define_expand "movhi"
+ [(set (match_operand:HI 0 "general_operand" "=g")
+ (match_operand:HI 1 "general_operand" "g"))]
+ ""
+ "
+ {
+ rtx op1 = operands[1];
+ if (GET_CODE (operands[0]) == MEM)
+ {
+ if (GET_CODE (op1) == MEM
+ || (GET_CODE (op1) == CONST_INT
+ && (INTVAL (op1) < 0 || INTVAL (op1) > 15)))
+ operands[1] = force_reg (HImode, operands[1]);
+ }
+ else if (GET_CODE (op1) == CONST_INT
+ && (INTVAL (op1) < -16 || INTVAL (op1) > 16))
+ operands[1] = force_const_mem (HImode, operands[1]);
+ }")
-;; Single-Float moves are *same* as HImode moves:
-;(define_insn "movhf"
-; [(set (match_operand:HF 0 "general_operand" "=r,r,r,m")
-; (match_operand:HF 1 "general_operand" "F,r,m,r"))]
-; ""
-; "@
-; %D1\;dl r%0,%F1
-; dlr r%0,r%1
-; dl r%0,%1
-; dst r%1,%0 ")
+;; Single-Float moves
-(define_insn "movhf"
- [(set (match_operand:HF 0 "general_operand" "=r,r,m")
- (match_operand:HF 1 "general_operand" "r,m,r"))]
+(define_insn ""
+ [(set (match_operand:HF 0 "general_operand" "=r,r,m,m")
+ (match_operand:HF 1 "general_operand" "r,m,r,G"))]
""
"@
- dlr r%0,r%1
- dl r%0,%1
- dst r%1,%0 ")
+ dlr r%0,r%1
+ dl r%0,%1
+ dst r%1,%0
+ stc 0,%0 \;stc 0,%A0 ")
+
+(define_expand "movhf"
+ [(set (match_operand:HF 0 "general_operand" "")
+ (match_operand:HF 1 "general_operand" ""))]
+ ""
+ "
+ {
+ enum rtx_code op1code = GET_CODE (operands[1]);
+ if (GET_CODE (operands[0]) == MEM)
+ {
+ if (op1code == MEM || (op1code == CONST_DOUBLE
+ && !rtx_equal_p (operands[1], CONST0_RTX (HFmode))))
+ operands[1] = force_reg (HFmode, operands[1]);
+ }
+ else if (op1code == CONST_DOUBLE)
+ operands[1] = force_const_mem (HFmode, operands[1]);
+ }")
;; Longfloat moves
-;(define_insn "movtqf"
-; [(set (match_operand:TQF 0 "general_operand" "=r,r,r,m")
-; (match_operand:TQF 1 "general_operand" "F,r,m,r"))]
-; ""
-; "@
-; %E1\;efl r%0,%G1
-; eflr.m %0,%1
-; efl r%0,%1
-; efst r%1,%0 ")
-
-(define_insn "movtqf"
+(define_insn ""
[(set (match_operand:TQF 0 "general_operand" "=r,r,m")
(match_operand:TQF 1 "general_operand" "r,m,r"))]
""
efl r%0,%1
efst r%1,%0 ")
+(define_expand "movtqf"
+ [(set (match_operand:TQF 0 "general_operand" "")
+ (match_operand:TQF 1 "general_operand" ""))]
+ ""
+ "
+ {
+ enum rtx_code op1code = GET_CODE (operands[1]);
+ if (GET_CODE (operands[0]) == MEM)
+ {
+ if (op1code == MEM || op1code == CONST_DOUBLE)
+ operands[1] = force_reg (TQFmode, operands[1]);
+ }
+ else if (op1code == CONST_DOUBLE)
+ operands[1] = force_const_mem (TQFmode, operands[1]);
+ }")
+
;; add instructions
;; single integer
-;; Use "LIM Ra,sym,Rb" for adding a symbol value to a register and
-;; transferring the result to a different register.
-;(define_insn ""
-; [(set (match_operand:QI 0 "register_operand" "=r")
-; (plus:QI (match_operand:QI 1 "register_operand" "b")
-; (match_operand:QI 2 "immediate_operand" "i")))]
-; "REGNO(operands[0]) != REGNO(operands[1])"
-; "lim r%0,%2,r%1 ;md special addqi")
-
(define_insn "addqi3"
[(set (match_operand:QI 0 "general_operand" "=r,r,r,r,r,m,m")
(plus:QI (match_operand:QI 1 "general_operand" "%0,0,0,0,0,0,0")
return \"incm %2,%0\";
case 6:
return \"decm %J2,%0\";
+ default:
+ abort();
} ")
;; double integer
(define_insn "addhf3"
[(set (match_operand:HF 0 "register_operand" "=r,r")
(plus:HF (match_operand:HF 1 "register_operand" "%0,0")
- (match_operand:HF 2 "general_operand" "m,r")))]
+ (match_operand:HF 2 "general_operand" "r,m")))]
""
"@
- fa r%0,%2
- far r%0,r%2 ")
+ far r%0,r%2
+ fa r%0,%2 ")
(define_insn "addtqf3"
[(set (match_operand:TQF 0 "register_operand" "=r,r")
(plus:TQF (match_operand:TQF 1 "register_operand" "%0,0")
- (match_operand:TQF 2 "general_operand" "m,r")))]
+ (match_operand:TQF 2 "general_operand" "r,m")))]
""
"@
- efa r%0,%2
- efar r%0,r%2 ")
+ efar r%0,r%2
+ efa r%0,%2 ")
;; subtract instructions
; 32-bit product
(define_insn "mulqihi3"
[(set (match_operand:HI 0 "register_operand" "=r,r,r")
- (mult:HI (match_operand:QI 1 "register_operand" "%0,0,0")
- (match_operand:QI 2 "general_operand" "M,r,m")))]
+ (mult:HI (sign_extend:HI (match_operand:QI 1 "register_operand" "%r,r,r"))
+ (sign_extend:HI (match_operand:QI 2 "general_operand" "r,m,i"))))]
""
- "@
- mim r%0,%1
- mr r%0,r%2
- m r%0,%2 ")
+ "*
+ if (REGNO (operands[1]) != REGNO (operands[0]))
+ output_asm_insn (\"lr r%0,r%1\", operands);
+
+ switch (which_alternative)
+ {
+ case 0:
+ return \"mr r%0,r%2\";
+ case 1:
+ return \"m r%0,%2\";
+ case 2:
+ return \"mim r%0,%2\";
+ default:
+ abort();
+ }
+ ")
+
(define_insn "mulhi3"
[(set (match_operand:HI 0 "register_operand" "=r,r")
""
"*
{
- char *istr;
+ const char *istr;
switch(which_alternative)
{
case 0:
istr = \"disp\";
break;
case 1:
- INTVAL(operands[2]) = - INTVAL(operands[2]); /* to be corrected */
- istr = \"disn\";
+ {
+ rtx new_opnds[4];
+ new_opnds[0] = operands[0];
+ new_opnds[1] = operands[1];
+ new_opnds[2] = GEN_INT (-INTVAL(operands[2]));
+ new_opnds[3] = operands[3];
+ istr = \"disn\";
+ return mod_regno_adjust (istr, new_opnds);
+ }
break;
case 2:
istr = \"dvim\";
istr = \"dv \";
break;
}
- return (char *)mod_regno_adjust(istr,operands);
+ return mod_regno_adjust (istr, operands);
}")
;; Division for other types is straightforward.
(neg:TQF (match_operand:TQF 1 "register_operand" "r")))]
""
"
- emit_insn(gen_rtx(SET,VOIDmode,operands[0],CONST0_RTX(TQFmode)));
- emit_insn(gen_rtx(SET,VOIDmode,operands[0],
- gen_rtx(MINUS,TQFmode,operands[0],operands[1])));
+ emit_insn (gen_rtx_SET (VOIDmode, operands[0], CONST0_RTX (TQFmode)));
+ emit_insn (gen_rtx_SET (VOIDmode, operands[0],
+ gen_rtx_MINUS (TQFmode, operands[0], operands[1])));
DONE;
")
;; bit-logical instructions
+;; Set Bit
+(define_insn ""
+ [(set (match_operand:QI 0 "general_operand" "=r,m")
+ (ior:QI (match_operand:QI 1 "general_operand" "0,0")
+ (match_operand:QI 2 "const_int_operand" "i,i")))]
+ "one_bit_set_p (INTVAL (operands [2]))"
+ "@
+ sbr %b2,r%0
+ sb %b2,%0")
+
+;; Reset Bit
+(define_insn ""
+ [(set (match_operand:QI 0 "general_operand" "=r,m")
+ (and:QI (match_operand:QI 1 "general_operand" "0,0")
+ (match_operand:QI 2 "const_int_operand" "i,i")))]
+ "one_bit_set_p ((~INTVAL (operands [2])) & 0xffff)"
+ "@
+ rbr %B2,r%0
+ rb %B2,%0")
+
+;; Set Variable Bit
+(define_insn ""
+ [(set (match_operand:QI 0 "register_operand" "=r")
+ (ior:QI (match_operand:QI 1 "register_operand" "0")
+ (lshiftrt:QI (const_int 32768)
+ (match_operand:QI 2 "register_operand" "r"))))]
+ ""
+ "svbr r%2,%r0")
+
+;; Reset Variable Bit
+(define_insn ""
+ [(set (match_operand:QI 0 "general_operand" "=r")
+ (and:QI (match_operand:QI 1 "general_operand" "0")
+ (not:QI (lshiftrt:QI (const_int 32768)
+ (match_operand:QI 2 "register_operand" "r")))))]
+ ""
+ "rvbr r%2,%r0")
+
+
;; AND
(define_insn "andqi3"
(define_insn "iorqi3"
[(set (match_operand:QI 0 "general_operand" "=r,r,r")
(ior:QI (match_operand:QI 1 "general_operand" "%0,0,0")
- (match_operand:QI 2 "general_operand" "M,r,m")))]
+ (match_operand:QI 2 "general_operand" "M,r,m")))]
""
"@
orim r%0,%2
; (What to the 1750 is logical-shift-left, GCC likes to call "arithmetic")
(define_insn "ashlqi3"
- [(set (match_operand:QI 0 "register_operand" "=r,r,r")
- (ashift:QI (match_operand:QI 1 "register_operand" "0,0,0")
- (match_operand:QI 2 "general_operand" "O,I,r")))]
+ [(set (match_operand:QI 0 "register_operand" "=r,r")
+ (ashift:QI (match_operand:QI 1 "register_operand" "0,0")
+ (match_operand:QI 2 "nonmemory_operand" "I,r")))]
""
"@
- ; optimized away an SLL r%0,0
sll r%0,%2
slr r%0,r%2 ")
(define_insn "ashlhi3"
[(set (match_operand:HI 0 "register_operand" "=r,r")
(ashift:HI (match_operand:HI 1 "register_operand" "0,0")
- (match_operand:QI 2 "general_operand" "L,r")))]
+ (match_operand:QI 2 "nonmemory_operand" "L,r")))]
"" ; the 'L' constraint is a slight imprecise...
- "@
- dsll r%0,%2
- dslr r%0,r%2 ")
+ "*
+ if (which_alternative == 1)
+ return \"dslr r%0,r%2\";
+ else if (INTVAL(operands[2]) <= 16)
+ return \"dsll r%0,%2\";
+ else
+ {
+ output_asm_insn (\"dsll r%0,16 ; ashlhi3 shiftcnt > 16\", operands);
+ return \"sll r%0,%w2\";
+ }
+ ")
-(define_insn "lshrqi3"
- [(set (match_operand:QI 0 "register_operand" "=r,r")
- (lshiftrt:QI (match_operand:QI 1 "register_operand" "0,0")
- (match_operand:QI 2 "general_operand" "I,r")))]
+
+;; Right shift by a variable shiftcount works by negating the shift count,
+;; then emitting a right shift with the shift count negated. This means
+;; that all actual shift counts in the RTL will be positive. This
+;; prevents converting shifts to ZERO_EXTRACTs with negative positions,
+;; which isn't valid.
+(define_expand "lshrqi3"
+ [(set (match_operand:QI 0 "register_operand" "=r")
+ (lshiftrt:QI (match_operand:QI 1 "register_operand" "0")
+ (match_operand:QI 2 "nonmemory_operand" "g")))]
""
- "@
- srl r%0,%2
- neg r%2,r%2\;slr r%0,r%2 ")
+ "
+{
+ if (GET_CODE (operands[2]) != CONST_INT)
+ operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2]));
+}")
-(define_insn "lshrhi3"
- [(set (match_operand:HI 0 "register_operand" "=r,r")
- (lshiftrt:HI (match_operand:HI 1 "register_operand" "0,0")
- (match_operand:QI 2 "general_operand" "L,r")))]
- "" ; the 'L' constraint is a slight imprecise...
- "@
- dsrl r%0,%2
- neg r%2,r%2\;dslr r%0,r%2 ")
+(define_insn ""
+ [(set (match_operand:QI 0 "register_operand" "=r")
+ (lshiftrt:QI (match_operand:QI 1 "register_operand" "0")
+ (match_operand:QI 2 "immediate_operand" "I")))]
+ ""
+ "srl r%0,%2")
-(define_insn "ashrqi3"
- [(set (match_operand:QI 0 "register_operand" "=r,r")
- (ashiftrt:QI (match_operand:QI 1 "register_operand" "0,0")
- (match_operand:QI 2 "general_operand" "I,r")))]
+(define_insn ""
+ [(set (match_operand:QI 0 "register_operand" "=r")
+ (lshiftrt:QI (match_operand:QI 1 "register_operand" "0")
+ (neg:QI (match_operand:QI 2 "register_operand" "r"))))]
""
- "@
- sra r%0,%2
- neg r%2,r%2\;sar r%0,r%2 ")
+ "slr r%0,r%2 ")
-(define_insn "ashrhi3"
- [(set (match_operand:HI 0 "register_operand" "=r,r")
- (ashiftrt:HI (match_operand:HI 1 "register_operand" "0,0")
- (match_operand:QI 2 "general_operand" "I,r")))]
+;; Same thing for HImode.
+
+(define_expand "lshrhi3"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
+ (match_operand:QI 2 "nonmemory_operand" "g")))]
""
- "@
- dsra r%0,%2
- neg r%2,r%2\;dsar r%0,r%2 ")
+ "
+ {
+ if (GET_CODE (operands[2]) != CONST_INT)
+ operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2]));
+ }")
+
+(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
+ (match_operand:QI 2 "immediate_operand" "L")))]
+ ""
+ "*
+ if (INTVAL (operands[2]) <= 16)
+ return \"dsrl r%0,%2\";
+ output_asm_insn (\"dsrl r%0,16 ; lshrhi3 shiftcount > 16\", operands);
+ return \"srl r%d0,%w2\";
+ ")
+
+(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (lshiftrt:HI (match_operand:HI 1 "register_operand" "0")
+ (neg:QI (match_operand:QI 2 "register_operand" "r"))))]
+ ""
+ "dslr r%0,r%2 ")
+
+;; Same applies for arithmetic shift right.
+(define_expand "ashrqi3"
+ [(set (match_operand:QI 0 "register_operand" "=r")
+ (ashiftrt:QI (match_operand:QI 1 "register_operand" "0")
+ (match_operand:QI 2 "nonmemory_operand" "g")))]
+ ""
+ "
+ {
+ if (GET_CODE (operands[2]) != CONST_INT)
+ operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2]));
+ }")
+
+(define_insn ""
+ [(set (match_operand:QI 0 "register_operand" "=r")
+ (ashiftrt:QI (match_operand:QI 1 "register_operand" "0")
+ (match_operand:QI 2 "immediate_operand" "I")))]
+ ""
+ "sra r%0,%2")
+
+(define_insn ""
+ [(set (match_operand:QI 0 "register_operand" "=r")
+ (ashiftrt:QI (match_operand:QI 1 "register_operand" "0")
+ (neg:QI (match_operand:QI 2 "register_operand" "r"))))]
+ ""
+ "sar r%0,r%2 ")
+
+;; HImode arithmetic shift right.
+(define_expand "ashrhi3"
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (ashiftrt:HI (match_operand:HI 1 "register_operand" "0")
+ (match_operand:QI 2 "nonmemory_operand" "g")))]
+ ""
+ "
+ {
+ if (GET_CODE (operands[2]) != CONST_INT)
+ operands[2] = gen_rtx_NEG (QImode, negate_rtx (QImode, operands[2]));
+ }")
+
+(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (ashiftrt:HI (match_operand:HI 1 "register_operand" "0")
+ (match_operand:QI 2 "immediate_operand" "L")))]
+ ""
+ "*
+ if (INTVAL (operands[2]) <= 16)
+ return \"dsra r%0,%2\";
+ output_asm_insn (\"dsra r%0,16 ; ashrhi3 shiftcount > 16\", operands);
+ return \"sra r%d0,%w2\";
+ ")
+
+(define_insn ""
+ [(set (match_operand:HI 0 "register_operand" "=r")
+ (ashiftrt:HI (match_operand:HI 1 "register_operand" "0")
+ (neg:QI (match_operand:QI 2 "register_operand" "r"))))]
+ ""
+ "dsar r%0,r%2 ")
;; rotate instructions
(define_insn "rotlqi3"
[(set (match_operand:QI 0 "register_operand" "=r,r")
(rotate:QI (match_operand:QI 1 "register_operand" "0,0")
- (match_operand:QI 2 "general_operand" "I,r")))]
+ (match_operand:QI 2 "nonmemory_operand" "I,r")))]
""
"@
slc r%0,%2
(define_insn "rotlhi3"
[(set (match_operand:HI 0 "register_operand" "=r,r")
(rotate:HI (match_operand:HI 1 "register_operand" "0,0")
- (match_operand:QI 2 "general_operand" "I,r")))]
+ (match_operand:QI 2 "nonmemory_operand" "I,r")))]
""
"@
dslc r%0,%2
(define_insn "rotrhi3"
[(set (match_operand:HI 0 "register_operand" "=r")
(rotatert:HI (match_operand:HI 1 "register_operand" "0")
- (match_operand:QI 2 "general_operand" "r")))]
+ (match_operand:QI 2 "nonmemory_operand" "r")))]
""
"neg r%2,r%2\;dscr r%0,r%2 ")
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "* return (char *)branch_or_jump(\"ez\",CODE_LABEL_NUMBER(operands[0]));
+ "* return branch_or_jump (\"ez\", CODE_LABEL_NUMBER (operands[0]));
")
(define_insn "bne"
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "* return (char *)branch_or_jump(\"nz\",CODE_LABEL_NUMBER(operands[0]));
+ "* return branch_or_jump (\"nz\", CODE_LABEL_NUMBER (operands[0]));
")
(define_insn "bgt"
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "* return (char *)branch_or_jump(\"gt\",CODE_LABEL_NUMBER(operands[0]));
+ "* return branch_or_jump (\"gt\", CODE_LABEL_NUMBER (operands[0]));
")
(define_insn "blt"
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "* return (char *)branch_or_jump(\"lt\",CODE_LABEL_NUMBER(operands[0]));
+ "* return branch_or_jump (\"lt\", CODE_LABEL_NUMBER (operands[0]));
")
(define_insn "bge"
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "* return (char *)branch_or_jump(\"ge\",CODE_LABEL_NUMBER(operands[0]));
+ "* return branch_or_jump (\"ge\", CODE_LABEL_NUMBER (operands[0]));
")
(define_insn "ble"
(label_ref (match_operand 0 "" ""))
(pc)))]
""
- "* return (char *)branch_or_jump(\"le\",CODE_LABEL_NUMBER(operands[0]));
+ "* return branch_or_jump (\"le\", CODE_LABEL_NUMBER (operands[0]));
")
(pc)
(label_ref (match_operand 0 "" ""))))]
""
- "* return (char *)branch_or_jump(\"nz\",CODE_LABEL_NUMBER(operands[0]));
+ "* return branch_or_jump (\"nz\", CODE_LABEL_NUMBER (operands[0]));
")
(define_insn ""
(pc)
(label_ref (match_operand 0 "" ""))))]
""
- "* return (char *)branch_or_jump(\"ez\",CODE_LABEL_NUMBER(operands[0]));
+ "* return branch_or_jump (\"ez\", CODE_LABEL_NUMBER (operands[0]));
")
(define_insn ""
(pc)
(label_ref (match_operand 0 "" ""))))]
""
- "* return (char *)branch_or_jump(\"le\",CODE_LABEL_NUMBER(operands[0]));
+ "* return branch_or_jump (\"le\", CODE_LABEL_NUMBER (operands[0]));
")
(define_insn ""
(pc)
(label_ref (match_operand 0 "" ""))))]
""
- "* return (char *)branch_or_jump(\"ge\",CODE_LABEL_NUMBER(operands[0]));
+ "* return branch_or_jump (\"ge\", CODE_LABEL_NUMBER (operands[0]));
")
(define_insn ""
(pc)
(label_ref (match_operand 0 "" ""))))]
""
- "* return (char *)branch_or_jump(\"lt\",CODE_LABEL_NUMBER(operands[0]));
+ "* return branch_or_jump (\"lt\", CODE_LABEL_NUMBER (operands[0]));
")
(define_insn ""
(pc)
(label_ref (match_operand 0 "" ""))))]
""
- "* return (char *)branch_or_jump(\"gt\",CODE_LABEL_NUMBER(operands[0]));
+ "* return branch_or_jump (\"gt\", CODE_LABEL_NUMBER (operands[0]));
")
;; Call subroutine, returning value in operand 0
;; (which must be a hard register).
(define_insn "call_value"
- [(set (match_operand 0 "register_operand" "r")
+ [(set (match_operand 0 "register_operand" "=r")
(call (match_operand:QI 1 "memory_operand" "m")
(match_operand:QI 2 "general_operand" "g")))]
;; Operand 2 not really used for 1750.
""
"ANYCALL %0")
-
-; (define_insn "return"
-; [(return)]
-; ""
-; "*
-; {
-; rtx oprnd = gen_rtx(CONST_INT,VOIDmode,get_frame_size());
-; output_asm_insn(\"ret.m %0\",&oprnd);
-; return \"\;\";
-; } ")
-
(define_insn "indirect_jump"
[(set (pc) (match_operand:QI 0 "address_operand" "p"))]
""
"INTVAL(operands[2]) == -1"
"soj r%0,%3")
-;; Load Base
+;; Combine a Load Register with subsequent increment/decrement into a LIM
(define_peephole
[(set (match_operand:QI 0 "register_operand" "=r")
- (mem:QI (plus:QI (match_operand:QI 1 "register_operand" "x")
- (match_operand:QI 2 "immediate_operand" "L"))))
- ]
- "REGNO(operands[0]) == 2 && REGNO(operands[1]) >= 12
- && INTVAL(operands[2]) <= 255"
- "lb r%1,%2")
-
-;; Double Load Base
-(define_peephole
- [(set (match_operand:HI 0 "register_operand" "=r")
- (mem:HI (plus:QI (match_operand:QI 1 "register_operand" "x")
- (match_operand:QI 2 "immediate_operand" "L"))))
- ]
- "REGNO(operands[0]) == 0 && REGNO(operands[1]) >= 12
- && INTVAL(operands[2]) <= 255"
- "dlb r%1,%2")
-
-(define_peephole
- [(set (match_operand:HF 0 "register_operand" "=r")
- (mem:HF (plus:QI (match_operand:QI 1 "register_operand" "x")
- (match_operand:QI 2 "immediate_operand" "L"))))
- ]
- "REGNO(operands[0]) == 0 && REGNO(operands[1]) >= 12
- && INTVAL(operands[2]) <= 255"
- "dlb r%1,%2")
-
-;; Store Base
-(define_peephole
- [(set (mem:QI (plus:QI (match_operand:QI 0 "register_operand" "x")
- (match_operand:QI 1 "immediate_operand" "L")))
- (match_operand:QI 2 "register_operand" "r"))
- ]
- "REGNO(operands[2]) == 2 && REGNO(operands[0]) >= 12
- && INTVAL(operands[1]) <= 255"
- "stb r%0,%1")
-
-;; Double Store Base
-(define_peephole
- [(set (mem:HI (plus:QI (match_operand:QI 0 "register_operand" "x")
- (match_operand:QI 1 "immediate_operand" "L")))
- (match_operand:HI 2 "register_operand" "r"))
- ]
- "REGNO(operands[2]) == 0 && REGNO(operands[0]) >= 12
- && INTVAL(operands[1]) <= 255"
- "dstb r%0,%1")
-
-(define_peephole
- [(set (mem:HF (plus:QI (match_operand:QI 0 "register_operand" "x")
- (match_operand:QI 1 "immediate_operand" "L")))
- (match_operand:HF 2 "register_operand" "r"))
- ]
- "REGNO(operands[2]) == 0 && REGNO(operands[0]) >= 12
- && INTVAL(operands[1]) <= 255"
- "dstb r%0,%1")
+ (match_operand:QI 1 "register_operand" "b"))
+ (set (match_dup 0)
+ (plus:QI (match_dup 0)
+ (match_operand:QI 2 "immediate_operand" "i")))]
+ "REGNO(operands[1]) > 0"
+ "lim r%0,%2,r%1 ; LR,inc/dec peephole")
;; Eliminate the redundant load in a store/load sequence
(define_peephole
[(set (mem:QI (plus:QI (match_operand:QI 0 "register_operand" "r")
- (match_operand:QI 1 "immediate_operand" "i")))
+ (match_operand:QI 1 "immediate_operand" "i")))
(match_operand:QI 2 "register_operand" "r"))
(set (match_operand:QI 3 "register_operand" "=r")
- (mem:QI (plus:QI (match_operand:QI 4 "register_operand" "r")
- (match_operand:QI 5 "immediate_operand" "i"))))
+ (mem:QI (plus:QI (match_dup 0)
+ (match_dup 1))))
]
- "REGNO(operands[2]) == REGNO(operands[3]) &&
- REGNO(operands[0]) == REGNO(operands[4]) &&
- INTVAL(operands[1]) == INTVAL(operands[5])"
+ "REGNO(operands[2]) == REGNO(operands[3])"
"st r%2,%1,r%0 ; eliminated previous redundant load")
;;;End.
-