ddd5a7c180
From-SVN: r9711
1260 lines
34 KiB
Markdown
1260 lines
34 KiB
Markdown
;;- Machine description for GNU compiler
|
|
;;- MIL-STD-1750A version.
|
|
;; Copyright (C) 1994 Free Software Foundation, Inc.
|
|
;; Contributed by O.M.Kellogg, DASA (okellogg@salyko.cube.net).
|
|
|
|
;; 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 definitions
|
|
|
|
;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.
|
|
|
|
;;- When naming insn's (operand 0 of define_insn) be careful about using
|
|
;;- names from other targets machine descriptions.
|
|
|
|
;; MIL-STD-1750 specific remarks:
|
|
;;
|
|
;; 1) BITS_PER_UNIT = 16
|
|
;;
|
|
;; 2) GCC to MIL-STD-1750 data type mappings:
|
|
;; QImode => single integer (16 bits or 1 reg).
|
|
;; HImode => double integer (32 bits or 2 regs).
|
|
;; HFmode => single precision float (32 bits or 2 regs).
|
|
;; TQFmode => extended precision float (48 bits or 3 regs).
|
|
;;
|
|
;; 3) Immediate integer operands Constraints:
|
|
;; 'I' 1 .. 16
|
|
;; 'J' -1 ..-16
|
|
;; 'K' 0 .. 15
|
|
;; 'L' 0 .. 255
|
|
;; 'M' -32768 .. 32767
|
|
;; 'O' => 0 (for optimizations and GCC quirks)
|
|
;;
|
|
;; Further notes:
|
|
;;- Assembly output ending in ".M" are macros in file M1750.INC
|
|
|
|
|
|
;; stackpush
|
|
(define_insn ""
|
|
[(set (match_operand:QI 0 "push_operand" "=<")
|
|
(match_operand:QI 1 "general_operand" "r"))]
|
|
""
|
|
"pshm r%1,r%1")
|
|
|
|
(define_insn ""
|
|
[(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);
|
|
} ")
|
|
|
|
(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 \"\;\";
|
|
} ")
|
|
|
|
(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 \"\;\";
|
|
} ")
|
|
|
|
;; stackpop
|
|
(define_insn ""
|
|
[(set (match_operand:QI 0 "general_operand" "=r")
|
|
(match_operand:QI 1 "push_operand" ">"))]
|
|
""
|
|
"popm r%1,r%1")
|
|
|
|
(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 \"\;\";
|
|
} ")
|
|
|
|
(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 \"\;\";
|
|
} ")
|
|
|
|
(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 \"\;\";
|
|
} ")
|
|
|
|
;; Test operations. These shouldn't really occur for 1750:
|
|
;; all important instructions set the cc's (see NOTICE_UPDATE_CC)
|
|
|
|
(define_insn "tstqi"
|
|
[(set (cc0)
|
|
(match_operand:QI 0 "register_operand" "r"))]
|
|
""
|
|
"lr r%0,r%0 ; from tstqi")
|
|
|
|
(define_insn "tsthi"
|
|
[(set (cc0)
|
|
(match_operand:HI 0 "register_operand" "r"))]
|
|
""
|
|
"dlr r%0,r%0 ; from tsthi")
|
|
|
|
(define_insn "tsthf"
|
|
[(set (cc0)
|
|
(match_operand:HF 0 "register_operand" "r"))]
|
|
""
|
|
"dlr r%0,r%0 ; from 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")
|
|
|
|
|
|
;; 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" ""))
|
|
(clobber (match_dup 0))
|
|
(clobber (match_dup 1))
|
|
(clobber (match_dup 2))]
|
|
""
|
|
"* return (char *)movcnt_regno_adjust(operands); ")
|
|
|
|
|
|
;; compare instructions.
|
|
|
|
(define_insn "cmpqi"
|
|
[(set (cc0)
|
|
(compare (match_operand:QI 0 "register_operand" "r,r,r,r,r")
|
|
(match_operand:QI 1 "general_operand" "I,J,i,r,m")))]
|
|
""
|
|
"@
|
|
cisp r%0,%1
|
|
cisn r%0,%J1
|
|
cim r%0,%1
|
|
cr r%0,r%1
|
|
c r%0,%1 ")
|
|
|
|
(define_insn "cmphi"
|
|
[(set (cc0)
|
|
(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 ")
|
|
|
|
(define_insn "cmphf"
|
|
[(set (cc0)
|
|
(compare (match_operand:HF 0 "general_operand" "r,r")
|
|
(match_operand:HF 1 "general_operand" "r,m")))]
|
|
""
|
|
"@
|
|
fcr r%0,r%1
|
|
fc r%0,%1 ")
|
|
|
|
(define_insn "cmptqf"
|
|
[(set (cc0)
|
|
(compare (match_operand:TQF 0 "general_operand" "r,r")
|
|
(match_operand:TQF 1 "general_operand" "r,m")))]
|
|
""
|
|
"@
|
|
efcr r%0,r%1
|
|
efc r%0,%1 ")
|
|
|
|
|
|
;; truncation instructions
|
|
;;- 1750: any needed?
|
|
|
|
(define_insn "trunchiqi2"
|
|
[(set (match_operand:QI 0 "register_operand" "=r")
|
|
(truncate:QI
|
|
(match_operand:HI 1 "register_operand" "r")))]
|
|
""
|
|
"*
|
|
{
|
|
REGNO(operands[1]) += 1;
|
|
return \"lr r%0,r%1 ;trunchiqi2\";
|
|
} ")
|
|
|
|
;; 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\";
|
|
}
|
|
} ")
|
|
|
|
;; 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")) )]
|
|
""
|
|
"@
|
|
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 ")
|
|
|
|
|
|
;; 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")))]
|
|
""
|
|
"*
|
|
{
|
|
REGNO(operands[0]) += 2;
|
|
output_asm_insn(\"xorr r%0,r%0 ;extendhftqf2\",operands);
|
|
REGNO(operands[0]) -= 2;
|
|
if (which_alternative == 0)
|
|
return \"dlr r%0,r%1\";
|
|
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"
|
|
[(set (match_operand:HF 0 "register_operand" "=r,r")
|
|
(float_truncate:HF
|
|
(match_operand:TQF 1 "general_operand" "r,m")))]
|
|
""
|
|
"@
|
|
dlr r%0,r%1 ;trunctqfhf2
|
|
dl r%0,%1 ;trunctqfhf2 ")
|
|
|
|
|
|
;; Conversion between fixed point and floating point.
|
|
|
|
(define_insn "floatqihf2"
|
|
[(set (match_operand:HF 0 "register_operand" "=r")
|
|
(float:HF (match_operand:QI 1 "register_operand" "r")))]
|
|
""
|
|
"flt r%0,r%1")
|
|
|
|
(define_insn "floathitqf2"
|
|
[(set (match_operand:TQF 0 "register_operand" "=r")
|
|
(float:TQF (match_operand:HI 1 "register_operand" "r")))]
|
|
""
|
|
"eflt r%0,r%1")
|
|
|
|
|
|
;; Convert floats to ints
|
|
|
|
(define_insn "fix_trunchfqi2"
|
|
[(set (match_operand:QI 0 "register_operand" "=r")
|
|
(fix:QI (fix:HF (match_operand:HF 1 "register_operand" "r"))))]
|
|
""
|
|
"fix r%0,r%1")
|
|
|
|
(define_insn "fix_trunctqfhi2"
|
|
[(set (match_operand:HI 0 "register_operand" "=r")
|
|
(fix:HI (fix:TQF (match_operand:TQF 1 "register_operand" "r"))))]
|
|
""
|
|
"efix r%0,r%1")
|
|
|
|
|
|
;; Move instructions
|
|
|
|
;; We can't deal with normal byte-size characters, only with WIDE characters!
|
|
;; This may appear as a serious restriction, but it also opens the doors
|
|
;; for ISO 10646 :-)
|
|
|
|
;; 16-bit moves
|
|
|
|
(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"))]
|
|
""
|
|
"@
|
|
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
|
|
lr r%0,r%1
|
|
l r%0,%1
|
|
st r%1,%0
|
|
stc %1,%0 ")
|
|
|
|
;; 32-bit moves
|
|
|
|
;; Set HIreg to constant
|
|
(define_insn ""
|
|
[(set (match_operand:HI 0 "register_operand" "=r")
|
|
(match_operand 1 "immediate_operand" "i"))]
|
|
""
|
|
"*
|
|
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\";
|
|
")
|
|
|
|
(define_insn "movhi"
|
|
[(set (match_operand:HI 0 "general_operand" "=r,r,m")
|
|
(match_operand:HI 1 "general_operand" "r,m,r"))]
|
|
""
|
|
"@
|
|
dlr r%0,r%1
|
|
dl r%0,%1
|
|
dst r%1,%0 ")
|
|
|
|
|
|
;; 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 ")
|
|
|
|
(define_insn "movhf"
|
|
[(set (match_operand:HF 0 "general_operand" "=r,r,m")
|
|
(match_operand:HF 1 "general_operand" "r,m,r"))]
|
|
""
|
|
"@
|
|
dlr r%0,r%1
|
|
dl r%0,%1
|
|
dst r%1,%0 ")
|
|
|
|
|
|
;; 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"
|
|
[(set (match_operand:TQF 0 "general_operand" "=r,r,m")
|
|
(match_operand:TQF 1 "general_operand" "r,m,r"))]
|
|
""
|
|
"@
|
|
eflr.m %0,%1
|
|
efl r%0,%1
|
|
efst r%1,%0 ")
|
|
|
|
|
|
;; 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")
|
|
(match_operand:QI 2 "general_operand" "I,J,i,r,m,I,J")))]
|
|
""
|
|
"*
|
|
switch (which_alternative)
|
|
{
|
|
case 0:
|
|
return \"aisp r%0,%2\";
|
|
case 1:
|
|
return \"sisp r%0,%J2\";
|
|
case 2:
|
|
if (INTVAL(operands[2]) < 0)
|
|
return \"sim r%0,%J2\";
|
|
else
|
|
return \"aim r%0,%2\";
|
|
case 3:
|
|
return \"ar r%0,r%2\";
|
|
case 4:
|
|
return \"a r%0,%2\";
|
|
case 5:
|
|
return \"incm %2,%0\";
|
|
case 6:
|
|
return \"decm %J2,%0\";
|
|
} ")
|
|
|
|
;; double integer
|
|
(define_insn "addhi3"
|
|
[(set (match_operand:HI 0 "register_operand" "=r,r")
|
|
(plus:HI (match_operand:HI 1 "register_operand" "%0,0")
|
|
(match_operand:HI 2 "general_operand" "r,m")))]
|
|
""
|
|
"@
|
|
dar r%0,r%2
|
|
da r%0,%2 ")
|
|
|
|
(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")))]
|
|
""
|
|
"@
|
|
fa r%0,%2
|
|
far r%0,r%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")))]
|
|
""
|
|
"@
|
|
efa r%0,%2
|
|
efar r%0,r%2 ")
|
|
|
|
|
|
;; subtract instructions
|
|
|
|
;; single integer
|
|
(define_insn "subqi3"
|
|
[(set (match_operand:QI 0 "general_operand" "=r,r,r,r,m")
|
|
(minus:QI (match_operand:QI 1 "general_operand" "0,0,0,0,0")
|
|
(match_operand:QI 2 "general_operand" "I,i,r,m,I")))]
|
|
""
|
|
"@
|
|
sisp r%0,%2
|
|
sim r%0,%2
|
|
sr r%0,r%2
|
|
s r%0,%2
|
|
decm %2,%0 ")
|
|
|
|
;; double integer
|
|
(define_insn "subhi3"
|
|
[(set (match_operand:HI 0 "register_operand" "=r,r")
|
|
(minus:HI (match_operand:HI 1 "register_operand" "0,0")
|
|
(match_operand:HI 2 "general_operand" "r,m")))]
|
|
""
|
|
"@
|
|
dsr r%0,r%2
|
|
ds r%0,%2 ")
|
|
|
|
(define_insn "subhf3"
|
|
[(set (match_operand:HF 0 "register_operand" "=r,r")
|
|
(minus:HF (match_operand:HF 1 "register_operand" "0,0")
|
|
(match_operand:HF 2 "general_operand" "r,m")))]
|
|
""
|
|
"@
|
|
fsr r%0,r%2
|
|
fs r%0,%2 ")
|
|
|
|
(define_insn "subtqf3"
|
|
[(set (match_operand:TQF 0 "register_operand" "=r,r")
|
|
(minus:TQF (match_operand:TQF 1 "register_operand" "0,0")
|
|
(match_operand:TQF 2 "general_operand" "r,m")))]
|
|
""
|
|
"@
|
|
efsr r%0,r%2
|
|
efs r%0,%2 ")
|
|
|
|
|
|
;; multiply instructions
|
|
|
|
(define_insn "mulqi3"
|
|
[(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r")
|
|
(mult:QI (match_operand:QI 1 "register_operand" "%0,0,0,0,0")
|
|
(match_operand:QI 2 "general_operand" "I,J,M,r,m")))]
|
|
""
|
|
"@
|
|
misp r%0,%2
|
|
misn r%0,%J2
|
|
msim r%0,%2
|
|
msr r%0,r%2
|
|
ms r%0,%2 ")
|
|
|
|
|
|
; 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")))]
|
|
""
|
|
"@
|
|
mim r%0,%1
|
|
mr r%0,r%2
|
|
m r%0,%2 ")
|
|
|
|
(define_insn "mulhi3"
|
|
[(set (match_operand:HI 0 "register_operand" "=r,r")
|
|
(mult:HI (match_operand:HI 1 "register_operand" "%0,0")
|
|
(match_operand:HI 2 "general_operand" "r,m")))]
|
|
""
|
|
"@
|
|
dmr r%0,r%2
|
|
dm r%0,%2 ")
|
|
|
|
; not available on 1750: "umulhi3","umulhisi3","umulsi3" (unsigned multiply's)
|
|
|
|
(define_insn "mulhf3"
|
|
[(set (match_operand:HF 0 "register_operand" "=r,r")
|
|
(mult:HF (match_operand:HF 1 "register_operand" "%0,0")
|
|
(match_operand:HF 2 "general_operand" "r,m")))]
|
|
""
|
|
"@
|
|
fmr r%0,r%2
|
|
fm r%0,%2 ")
|
|
|
|
(define_insn "multqf3"
|
|
[(set (match_operand:TQF 0 "register_operand" "=r,r")
|
|
(mult:TQF (match_operand:TQF 1 "register_operand" "%0,0")
|
|
(match_operand:TQF 2 "general_operand" "r,m")))]
|
|
""
|
|
"@
|
|
efmr r%0,r%2
|
|
efm r%0,%2 ")
|
|
|
|
|
|
;; divide instructions
|
|
;; The 1750 16bit integer division instructions deliver a 16-bit
|
|
;; quotient and a 16-bit remainder, where the remainder is in the next higher
|
|
;; register number above the quotient. For now, we haven't found a way
|
|
;; to give the reload pass knowledge of this property. So we make do with
|
|
;; whatever registers the allocator wants, and willy-nilly output a pair of
|
|
;; register-copy ops when needed. (See mod_regno_adjust() in file aux-output.c)
|
|
;; A comment in the description of `divmodM4' suggests that one leave the divM3
|
|
;; undefined when there is a divmodM4 available.
|
|
|
|
(define_insn "divmodqi4"
|
|
[(set (match_operand:QI 0 "register_operand" "=r,r,r,r,r")
|
|
(div:QI (match_operand:QI 1 "register_operand" "0,0,0,0,0")
|
|
(match_operand:QI 2 "general_operand" "I,J,M,r,m")))
|
|
(set (match_operand:QI 3 "register_operand" "=r,r,r,r,r")
|
|
(mod:QI (match_dup 1) (match_dup 2)))]
|
|
""
|
|
"*
|
|
{
|
|
char *istr;
|
|
switch(which_alternative)
|
|
{
|
|
case 0:
|
|
istr = \"disp\";
|
|
break;
|
|
case 1:
|
|
INTVAL(operands[2]) = - INTVAL(operands[2]); /* to be corrected */
|
|
istr = \"disn\";
|
|
break;
|
|
case 2:
|
|
istr = \"dvim\";
|
|
break;
|
|
case 3:
|
|
istr = \"dvr \";
|
|
break;
|
|
case 4:
|
|
istr = \"dv \";
|
|
break;
|
|
}
|
|
return (char *)mod_regno_adjust(istr,operands);
|
|
}")
|
|
|
|
;; Division for other types is straightforward.
|
|
|
|
(define_insn "divhi3"
|
|
[(set (match_operand:HI 0 "register_operand" "=r,r")
|
|
(div:HI (match_operand:HI 1 "register_operand" "0,0")
|
|
(match_operand:HI 2 "general_operand" "r,m")))]
|
|
""
|
|
"@
|
|
ddr r%0,r%2
|
|
dd r%0,%2 ")
|
|
|
|
(define_insn "divhf3"
|
|
[(set (match_operand:HF 0 "register_operand" "=r,r")
|
|
(div:HF (match_operand:HF 1 "register_operand" "0,0")
|
|
(match_operand:HF 2 "general_operand" "r,m")))]
|
|
""
|
|
"@
|
|
fdr r%0,r%2
|
|
fd r%0,%2 ")
|
|
|
|
(define_insn "divtqf3"
|
|
[(set (match_operand:TQF 0 "register_operand" "=r,r")
|
|
(div:TQF (match_operand:TQF 1 "register_operand" "0,0")
|
|
(match_operand:TQF 2 "general_operand" "r,m")))]
|
|
""
|
|
"@
|
|
efdr r%0,r%2
|
|
efd r%0,%2 ")
|
|
|
|
|
|
;; Other arithmetic instructions:
|
|
|
|
;; Absolute value
|
|
|
|
(define_insn "absqi2"
|
|
[(set (match_operand:QI 0 "register_operand" "=r")
|
|
(abs:QI (match_operand:QI 1 "register_operand" "r")))]
|
|
""
|
|
"abs r%0,r%1")
|
|
|
|
(define_insn "abshi2"
|
|
[(set (match_operand:HI 0 "register_operand" "=r")
|
|
(abs:HI (match_operand:HI 1 "register_operand" "r")))]
|
|
""
|
|
"dabs r%0,r%1")
|
|
|
|
(define_insn "abshf2"
|
|
[(set (match_operand:HF 0 "register_operand" "=r")
|
|
(abs:HF (match_operand:HF 1 "register_operand" "r")))]
|
|
""
|
|
"fabs r%0,r%1")
|
|
|
|
|
|
;; Negation
|
|
|
|
(define_insn "negqi2"
|
|
[(set (match_operand:QI 0 "register_operand" "=r")
|
|
(neg:QI (match_operand:QI 1 "register_operand" "r")))]
|
|
""
|
|
"neg r%0,r%1")
|
|
|
|
(define_insn "neghi2"
|
|
[(set (match_operand:HI 0 "register_operand" "=r")
|
|
(neg:HI (match_operand:HI 1 "register_operand" "r")))]
|
|
""
|
|
"dneg r%0,r%1")
|
|
|
|
(define_insn "neghf2"
|
|
[(set (match_operand:HF 0 "register_operand" "=r")
|
|
(neg:HF (match_operand:HF 1 "register_operand" "r")))]
|
|
""
|
|
"fneg r%0,r%1")
|
|
|
|
; The 1750A does not have an extended float negate instruction, so simulate.
|
|
(define_expand "negtqf2"
|
|
[(set (match_operand:TQF 0 "register_operand" "=&r")
|
|
(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])));
|
|
DONE;
|
|
")
|
|
|
|
|
|
;; bit-logical instructions
|
|
|
|
;; AND
|
|
|
|
(define_insn "andqi3"
|
|
[(set (match_operand:QI 0 "general_operand" "=r,r,r")
|
|
(and:QI (match_operand:QI 1 "general_operand" "%0,0,0")
|
|
(match_operand:QI 2 "general_operand" "M,r,m")))]
|
|
""
|
|
"@
|
|
andm r%0,%2
|
|
andr r%0,r%2
|
|
and r%0,%2 ")
|
|
|
|
; This sets incorrect condition codes. See notice_update_cc()
|
|
(define_insn "andhi3"
|
|
[(set (match_operand:HI 0 "register_operand" "=r")
|
|
(and:HI (match_operand:HI 1 "register_operand" "%0")
|
|
(match_operand:HI 2 "register_operand" "r")))]
|
|
""
|
|
"danr.m %0,%2")
|
|
|
|
;; OR
|
|
|
|
(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")))]
|
|
""
|
|
"@
|
|
orim r%0,%2
|
|
orr r%0,r%2
|
|
or r%0,%2 ")
|
|
|
|
; This sets incorrect condition codes. See notice_update_cc()
|
|
(define_insn "iorhi3"
|
|
[(set (match_operand:HI 0 "register_operand" "=r")
|
|
(ior:HI (match_operand:HI 1 "register_operand" "%0")
|
|
(match_operand:HI 2 "register_operand" "r")))]
|
|
""
|
|
"dorr.m %0,%2")
|
|
|
|
;; XOR
|
|
|
|
(define_insn "xorqi3"
|
|
[(set (match_operand:QI 0 "register_operand" "=r,r,r")
|
|
(xor:QI (match_operand:QI 1 "register_operand" "%0,0,0")
|
|
(match_operand:QI 2 "general_operand" "M,r,m")))]
|
|
""
|
|
"@
|
|
xorm r%0,%2
|
|
xorr r%0,r%2
|
|
xor r%0,%2 ")
|
|
|
|
; This sets incorrect condition codes. See notice_update_cc()
|
|
(define_insn "xorhi3"
|
|
[(set (match_operand:HI 0 "register_operand" "=r")
|
|
(xor:HI (match_operand:HI 1 "register_operand" "%0")
|
|
(match_operand:HI 2 "register_operand" "r")))]
|
|
""
|
|
"dxrr.m %0,%2")
|
|
|
|
;; NAND
|
|
|
|
(define_insn ""
|
|
[(set (match_operand:QI 0 "register_operand" "=r,r,r")
|
|
(ior:QI (not:QI (match_operand:QI 1 "register_operand" "%0,0,0"))
|
|
(not:QI (match_operand:QI 2 "general_operand" "M,r,m"))))]
|
|
""
|
|
"@
|
|
nim r%0,%2
|
|
nr r%0,r%2
|
|
n r%0,%2 ")
|
|
|
|
; This sets incorrect condition codes. See notice_update_cc()
|
|
(define_insn ""
|
|
[(set (match_operand:HI 0 "register_operand" "=r")
|
|
(ior:HI (not:HI (match_operand:HI 1 "register_operand" "%0"))
|
|
(not:HI (match_operand:HI 2 "register_operand" "r"))))]
|
|
""
|
|
"dnr.m %0,%2")
|
|
|
|
;; NOT
|
|
|
|
(define_insn "one_cmplqi2"
|
|
[(set (match_operand:QI 0 "register_operand" "=r")
|
|
(not:QI (match_operand:QI 1 "register_operand" "0")))]
|
|
""
|
|
"nr r%0,r%0")
|
|
|
|
; This sets incorrect condition codes. See notice_update_cc()
|
|
(define_insn "one_cmplhi2"
|
|
[(set (match_operand:HI 0 "register_operand" "=r")
|
|
(not:HI (match_operand:HI 1 "register_operand" "0")))]
|
|
""
|
|
"dnr.m %0,%0")
|
|
|
|
|
|
;; Shift instructions
|
|
|
|
; (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")))]
|
|
""
|
|
"@
|
|
; 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")))]
|
|
"" ; the 'L' constraint is a slight imprecise...
|
|
"@
|
|
dsll r%0,%2
|
|
dslr r%0,r%2 ")
|
|
|
|
(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")))]
|
|
""
|
|
"@
|
|
srl r%0,%2
|
|
neg r%2,r%2\;slr r%0,r%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 "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")))]
|
|
""
|
|
"@
|
|
sra r%0,%2
|
|
neg r%2,r%2\;sar 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")))]
|
|
""
|
|
"@
|
|
dsra r%0,%2
|
|
neg r%2,r%2\;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")))]
|
|
""
|
|
"@
|
|
slc r%0,%2
|
|
scr r%0,r%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")))]
|
|
""
|
|
"@
|
|
dslc r%0,%2
|
|
dscr r%0,r%2 ")
|
|
|
|
(define_insn "rotrqi3"
|
|
[(set (match_operand:QI 0 "register_operand" "=r,r")
|
|
(rotatert:QI (match_operand:QI 1 "register_operand" "0,0")
|
|
(match_operand:QI 2 "general_operand" "I,r")))]
|
|
""
|
|
"@
|
|
slc r%0,%2
|
|
neg r%2,r%2\;scr r%0,r%2 ")
|
|
|
|
(define_insn "rotrhi3"
|
|
[(set (match_operand:HI 0 "register_operand" "=r,r")
|
|
(rotatert:HI (match_operand:HI 1 "register_operand" "0,0")
|
|
(match_operand:QI 2 "general_operand" "I,r")))]
|
|
""
|
|
"@
|
|
dslc r%0,%2
|
|
neg r%2,r%2\;dscr r%0,r%2 ")
|
|
|
|
|
|
|
|
;; Special cases of bit-field insns which we should
|
|
;; recognize in preference to the general case.
|
|
;; These handle aligned 8-bit and 16-bit fields,
|
|
;; which can usually be done with move instructions.
|
|
; 1750: t.b.d.
|
|
;********************
|
|
|
|
;; Bit field instructions, general cases.
|
|
;; "o,d" constraint causes a nonoffsettable memref to match the "o"
|
|
;; so that its address is reloaded.
|
|
|
|
;; (define_insn "extv" ...
|
|
|
|
;; (define_insn "extzv" ...
|
|
|
|
;; (define_insn "insv" ...
|
|
|
|
;; Now recognize bit field insns that operate on registers
|
|
;; (or at least were intended to do so).
|
|
;[unnamed only]
|
|
|
|
;; Special patterns for optimizing bit-field instructions.
|
|
;**************************************
|
|
|
|
; cc status test ops n.a. on 1750 ......... e.g. "sleu" on 68k:
|
|
; [(set (match_operand:QI 0 "general_operand" "=d")
|
|
; (leu (cc0) (const_int 0)))]
|
|
; ""
|
|
; "* cc_status = cc_prev_status;
|
|
; return \"sls %0\"; ")
|
|
|
|
|
|
;; Basic conditional jump instructions.
|
|
|
|
(define_insn "beq"
|
|
[(set (pc)
|
|
(if_then_else (eq (cc0)
|
|
(const_int 0))
|
|
(label_ref (match_operand 0 "" ""))
|
|
(pc)))]
|
|
""
|
|
"* return (char *)branch_or_jump(\"ez\",CODE_LABEL_NUMBER(operands[0]));
|
|
")
|
|
|
|
(define_insn "bne"
|
|
[(set (pc)
|
|
(if_then_else (ne (cc0)
|
|
(const_int 0))
|
|
(label_ref (match_operand 0 "" ""))
|
|
(pc)))]
|
|
""
|
|
"* return (char *)branch_or_jump(\"nz\",CODE_LABEL_NUMBER(operands[0]));
|
|
")
|
|
|
|
(define_insn "bgt"
|
|
[(set (pc)
|
|
(if_then_else (gt (cc0)
|
|
(const_int 0))
|
|
(label_ref (match_operand 0 "" ""))
|
|
(pc)))]
|
|
""
|
|
"* return (char *)branch_or_jump(\"gt\",CODE_LABEL_NUMBER(operands[0]));
|
|
")
|
|
|
|
(define_insn "blt"
|
|
[(set (pc)
|
|
(if_then_else (lt (cc0)
|
|
(const_int 0))
|
|
(label_ref (match_operand 0 "" ""))
|
|
(pc)))]
|
|
""
|
|
"* return (char *)branch_or_jump(\"lt\",CODE_LABEL_NUMBER(operands[0]));
|
|
")
|
|
|
|
(define_insn "bge"
|
|
[(set (pc)
|
|
(if_then_else (ge (cc0)
|
|
(const_int 0))
|
|
(label_ref (match_operand 0 "" ""))
|
|
(pc)))]
|
|
""
|
|
"* return (char *)branch_or_jump(\"ge\",CODE_LABEL_NUMBER(operands[0]));
|
|
")
|
|
|
|
(define_insn "ble"
|
|
[(set (pc)
|
|
(if_then_else (le (cc0)
|
|
(const_int 0))
|
|
(label_ref (match_operand 0 "" ""))
|
|
(pc)))]
|
|
""
|
|
"* return (char *)branch_or_jump(\"le\",CODE_LABEL_NUMBER(operands[0]));
|
|
")
|
|
|
|
|
|
; no unsigned branches available on 1750. But GCC still needs them, so faking:
|
|
|
|
(define_insn "bgtu"
|
|
[(set (pc)
|
|
(if_then_else (gtu (cc0)
|
|
(const_int 0))
|
|
(label_ref (match_operand 0 "" ""))
|
|
(pc)))]
|
|
""
|
|
"jc gt,%l0 ; Warning: this should be an *unsigned* test!")
|
|
|
|
(define_insn "bltu"
|
|
[(set (pc)
|
|
(if_then_else (ltu (cc0)
|
|
(const_int 0))
|
|
(label_ref (match_operand 0 "" ""))
|
|
(pc)))]
|
|
""
|
|
"jc lt,%l0 ; Warning: this should be an *unsigned* test!")
|
|
|
|
(define_insn "bgeu"
|
|
[(set (pc)
|
|
(if_then_else (geu (cc0)
|
|
(const_int 0))
|
|
(label_ref (match_operand 0 "" ""))
|
|
(pc)))]
|
|
""
|
|
"jc ge,%l0 ; Warning: this should be an *unsigned* test!")
|
|
|
|
(define_insn "bleu"
|
|
[(set (pc)
|
|
(if_then_else (leu (cc0)
|
|
(const_int 0))
|
|
(label_ref (match_operand 0 "" ""))
|
|
(pc)))]
|
|
""
|
|
"jc le,%l0 ; Warning: this should be an *unsigned* test!")
|
|
|
|
|
|
;; Negated conditional jump instructions.
|
|
|
|
(define_insn ""
|
|
[(set (pc)
|
|
(if_then_else (eq (cc0)
|
|
(const_int 0))
|
|
(pc)
|
|
(label_ref (match_operand 0 "" ""))))]
|
|
""
|
|
"* return (char *)branch_or_jump(\"nz\",CODE_LABEL_NUMBER(operands[0]));
|
|
")
|
|
|
|
(define_insn ""
|
|
[(set (pc)
|
|
(if_then_else (ne (cc0)
|
|
(const_int 0))
|
|
(pc)
|
|
(label_ref (match_operand 0 "" ""))))]
|
|
""
|
|
"* return (char *)branch_or_jump(\"ez\",CODE_LABEL_NUMBER(operands[0]));
|
|
")
|
|
|
|
(define_insn ""
|
|
[(set (pc)
|
|
(if_then_else (gt (cc0)
|
|
(const_int 0))
|
|
(pc)
|
|
(label_ref (match_operand 0 "" ""))))]
|
|
""
|
|
"* return (char *)branch_or_jump(\"le\",CODE_LABEL_NUMBER(operands[0]));
|
|
")
|
|
|
|
(define_insn ""
|
|
[(set (pc)
|
|
(if_then_else (lt (cc0)
|
|
(const_int 0))
|
|
(pc)
|
|
(label_ref (match_operand 0 "" ""))))]
|
|
""
|
|
"* return (char *)branch_or_jump(\"ge\",CODE_LABEL_NUMBER(operands[0]));
|
|
")
|
|
|
|
(define_insn ""
|
|
[(set (pc)
|
|
(if_then_else (ge (cc0)
|
|
(const_int 0))
|
|
(pc)
|
|
(label_ref (match_operand 0 "" ""))))]
|
|
""
|
|
"* return (char *)branch_or_jump(\"lt\",CODE_LABEL_NUMBER(operands[0]));
|
|
")
|
|
|
|
(define_insn ""
|
|
[(set (pc)
|
|
(if_then_else (le (cc0)
|
|
(const_int 0))
|
|
(pc)
|
|
(label_ref (match_operand 0 "" ""))))]
|
|
""
|
|
"* return (char *)branch_or_jump(\"gt\",CODE_LABEL_NUMBER(operands[0]));
|
|
")
|
|
|
|
|
|
;; Negated unsigned conditional jump instructions (faked for 1750).
|
|
|
|
(define_insn ""
|
|
[(set (pc)
|
|
(if_then_else (gtu (cc0)
|
|
(const_int 0))
|
|
(pc)
|
|
(label_ref (match_operand 0 "" ""))))]
|
|
""
|
|
"jc le,%l0 ;inv.cond. ;Warning: this should be an *unsigned* test!")
|
|
|
|
(define_insn ""
|
|
[(set (pc)
|
|
(if_then_else (ltu (cc0)
|
|
(const_int 0))
|
|
(pc)
|
|
(label_ref (match_operand 0 "" ""))))]
|
|
""
|
|
"jc ge,%l0 ;inv.cond. ;Warning: this should be an *unsigned* test!")
|
|
|
|
(define_insn ""
|
|
[(set (pc)
|
|
(if_then_else (geu (cc0)
|
|
(const_int 0))
|
|
(pc)
|
|
(label_ref (match_operand 0 "" ""))))]
|
|
""
|
|
"jc lt,%l0 ;inv.cond. ;Warning: this should be an *unsigned* test!")
|
|
|
|
(define_insn ""
|
|
[(set (pc)
|
|
(if_then_else (leu (cc0)
|
|
(const_int 0))
|
|
(pc)
|
|
(label_ref (match_operand 0 "" ""))))]
|
|
""
|
|
"jc gt,%l0 ;inv.cond. ;Warning: this should be an *unsigned* test!")
|
|
|
|
;; Tablejump
|
|
;; 1750 note: CASE_VECTOR_PC_RELATIVE is not defined
|
|
(define_insn "tablejump"
|
|
[(set (pc)
|
|
(match_operand:QI 0 "register_operand" "b"))
|
|
(use (label_ref (match_operand 1 "" "")))]
|
|
""
|
|
"jc 15,0,r%0 ; tablejump label_ref=%1")
|
|
|
|
|
|
;; Unconditional jump
|
|
(define_insn "jump"
|
|
[(set (pc)
|
|
(label_ref (match_operand 0 "" "")))]
|
|
""
|
|
"jc uc,%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")
|
|
(call (match_operand:QI 1 "memory_operand" "m")
|
|
(match_operand:QI 2 "general_operand" "g")))]
|
|
;; Operand 2 not really used for 1750.
|
|
""
|
|
"sjs r15,%1 ; return value in R0")
|
|
|
|
;; Call subroutine with no return value.
|
|
|
|
;; Operand 1 not really used in MIL-STD-1750.
|
|
(define_insn ""
|
|
[(call (match_operand:QI 0 "memory_operand" "mp")
|
|
(match_operand:QI 1 "general_operand" ""))]
|
|
""
|
|
"sjs r15,%0 ; no return value")
|
|
|
|
;;;;;;;;;;;; 1750: NOT READY YET.
|
|
(define_insn "call"
|
|
[(call (match_operand:QI 0 "" "")
|
|
(match_operand:QI 1 "" ""))]
|
|
""
|
|
"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"))]
|
|
""
|
|
"jci 15,%0")
|
|
|
|
(define_insn "nop"
|
|
[(const_int 0)]
|
|
""
|
|
"nop")
|
|
|
|
|
|
;; Subtract One and Jump (if non-zero)
|
|
(define_peephole
|
|
[(set (match_operand:QI 0 "register_operand" "=r")
|
|
(plus:QI (match_operand:QI 1 "register_operand" "%0")
|
|
(match_operand:QI 2 "immediate_operand" "J")))
|
|
(set (cc0) (match_dup 0))
|
|
(set (pc)
|
|
(if_then_else (ne (cc0) (const_int 0))
|
|
(label_ref (match_operand 3 "" ""))
|
|
(pc)))
|
|
]
|
|
"INTVAL(operands[2]) == -1"
|
|
"soj r%0,%3")
|
|
|
|
;;;End.
|
|
|