Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
riscv-gcc-1
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
riscv-gcc-1
Commits
d12a2c91
Commit
d12a2c91
authored
Mar 14, 1992
by
Torbjorn Granlund
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Initial revision
From-SVN: r474
parent
448ff736
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
2660 additions
and
0 deletions
+2660
-0
gcc/config/gmicro/gmicro.md
+2660
-0
No files found.
gcc/config/gmicro/gmicro.md
0 → 100644
View file @
d12a2c91
;;- Machine description for GNU compiler
;;- Fujitsu Gmicro Version
;;- Ported by M.Yuhara, Fujitsu Laboratories LTD.
;;
;; Copyright (C) 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 2, or (at your option)
;; any later version.
;; GNU CC is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; Among other things, the copyright
;; notice and this notice must be preserved on all copies.
;; 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.
;;- cpp macro #define NOTICE_UPDATE_CC is essentially a no-op for the
;;- gmicro; no compares are eliminated.
;;- The original structure of this file is m68k.md.
;; ??? Work to be done:
;; Add patterns for ACB and SCB instructions.
;; Add define_insn patterns to recognize the insns that extend a byte
;; to a word and add it into a word, etc.
;;- Some of these insn's are composites of several Gmicro op codes.
;;- The assembler (or final @@??) insures that the appropriate one is
;;- selected.
(define_insn ""
[
(set (match_operand:DF 0 "push_operand" "=m")
(match_operand:DF 1 "general_operand" "rmfF"))]
""
"
*
{
if (FPU_REG_P (operands
[
1
]
))
return
\"
fmov.d %f1,%0
\"
;
return output_move_double (operands);
}")
(define_insn ""
[
(set (match_operand:DI 0 "push_operand" "=m")
(match_operand:DF 1 "general_operand" "rmF"))]
""
"
*
{
return output_move_double (operands);
}")
;; We don't want to allow a constant operand for test insns because
;; (set (cc0) (const_int foo)) has no mode information. Such insns will
;; be folded while optimizing anyway.
(define_insn "tstsi"
[
(set (cc0)
(match_operand:SI 0 "nonimmediate_operand" "rm"))]
""
"cmp:z.w #0,%0")
(define_insn "tsthi"
[
(set (cc0)
(match_operand:HI 0 "nonimmediate_operand" "rm"))]
""
"cmp:z.h #0,%0")
(define_insn "tstqi"
[
(set (cc0)
(match_operand:QI 0 "nonimmediate_operand" "rm"))]
""
"cmp:z.b #0,%0")
(define_insn "tstsf"
[
(set (cc0)
(match_operand:SF 0 "general_operand" "fmF"))]
"TARGET_FPU"
"
*
{
cc_status.flags = CC_IN_FPU;
return
\"
ftst.s %0
\"
;
}")
(define_insn "tstdf"
[
(set (cc0)
(match_operand:DF 0 "general_operand" "fmF"))]
"TARGET_FPU"
"
*
{
cc_status.flags = CC_IN_FPU;
return
\"
ftst.d %0
\"
;
}")
;; compare instructions.
;; (operand0 - operand1)
(define_insn "cmpsi"
[
(set (cc0)
(compare (match_operand:SI 0 "nonimmediate_operand" "ri,rm")
(match_operand:SI 1 "general_operand" "rm,rmi")))]
""
"
*
{
int signed_flag = my_signed_comp (insn);
if (which_alternative == 0)
{
cc_status.flags |= CC_REVERSED;
if (signed_flag && GET_CODE (operands
[
0
]
) == CONST_INT)
{
register rtx xfoo;
xfoo = operands
[
1
]
;
operands
[
0
]
= operands
[
1
]
;
operands
[
1
]
= xfoo;
return cmp_imm_word (INTVAL (operands
[
1
]
), operands
[
0
]
);
}
if (signed_flag)
return
\"
cmp.w %0,%1
\"
;
return
\"
cmpu.w %0,%1
\"
;
}
if (signed_flag)
{
if (GET_CODE (operands
[
1
]
) == CONST_INT)
return cmp_imm_word (INTVAL (operands
[
1
]
), operands
[
0
]
);
return
\"
cmp.w %1,%0
\"
;
}
else
return
\"
cmpu.w %1,%0
\"
;
}")
(define_insn "cmphi"
[
(set (cc0)
(compare (match_operand:HI 0 "nonimmediate_operand" "ri,rm")
(match_operand:HI 1 "general_operand" "rm,rmi")))]
""
"
*
{
int signed_flag = my_signed_comp (insn);
if (which_alternative == 0)
{
cc_status.flags |= CC_REVERSED;
if (signed_flag)
return
\"
cmp.h %0,%1
\"
;
return
\"
cmpu.h %0,%1
\"
;
}
if (signed_flag)
return
\"
cmp.h %1,%0
\"
;
return
\"
cmpu.h %1,%0
\"
;
}")
(define_insn "cmpqi"
[
(set (cc0)
(compare (match_operand:QI 0 "nonimmediate_operand" "ri,rm")
(match_operand:QI 1 "general_operand" "rm,rmi")))]
""
"
*
{
int signed_flag = my_signed_comp (insn);
if (which_alternative == 0)
{
cc_status.flags |= CC_REVERSED;
if (signed_flag)
return
\"
cmp.b %0,%1
\"
;
return
\"
cmpu.b %0,%1
\"
;
}
if (signed_flag)
return
\"
cmp.b %1,%0
\"
;
return
\"
cmpu.b %1,%0
\"
;
}")
(define_insn "cmpdf"
[
(set (cc0)
(compare (match_operand:DF 0 "general_operand" "f,mG")
(match_operand:DF 1 "general_operand" "fmG,f")))]
"TARGET_FPU"
"
*
{
cc_status.flags = CC_IN_FPU;
if (FPU_REG_P (operands
[
0
]
))
return
\"
fcmp.d %f1,%f0
\"
;
cc_status.flags |= CC_REVERSED;
return
\"
fcmp.d %f0,%f1
\"
;
}")
(define_insn "cmpsf"
[
(set (cc0)
(compare (match_operand:SF 0 "general_operand" "f,mG")
(match_operand:SF 1 "general_operand" "fmG,f")))]
"TARGET_FPU"
"
*
{
cc_status.flags = CC_IN_FPU;
if (FPU_REG_P (operands
[
0
]
))
return
\"
fcmp.s %f1,%0
\"
;
cc_status.flags |= CC_REVERSED;
return
\"
fcmp.s %f0,%1
\"
;
}")
;; Recognizers for btst instructions.
(define_insn ""
[
(set (cc0) (zero_extract (match_operand:QI 0 "nonimmediate_operand" "rm")
(const_int 1)
(match_operand:SI 1 "general_operand" "rmi")))]
""
"btst %1.w,%0.b")
(define_insn ""
[
(set (cc0) (zero_extract (match_operand:HI 0 "nonimmediate_operand" "rm")
(const_int 1)
(match_operand:SI 1 "general_operand" "rmi")))]
""
"btst %1.w,%0.h")
(define_insn ""
[
(set (cc0) (zero_extract (match_operand:SI 0 "nonimmediate_operand" "rm")
(const_int 1)
(match_operand:SI 1 "general_operand" "rmi")))]
""
"btst %1.w,%0.w")
;; The following two patterns are like the previous two
;; except that they use the fact that bit-number operands (offset)
;; are automatically masked to 3 or 5 bits when the base is a register.
(define_insn ""
[
(set (cc0) (zero_extract (match_operand:QI 0 "nonimmediate_operand" "r")
(const_int 1)
(and:SI
(match_operand:SI 1 "general_operand" "rmi")
(const_int 7))))]
""
"btst %1.w,%0.b")
(define_insn ""
[
(set (cc0) (zero_extract (match_operand:SI 0 "nonimmediate_operand" "r")
(const_int 1)
(and:SI
(match_operand:SI 1 "general_operand" "rmi")
(const_int 31))))]
""
"btst %1.w,%0.w")
; More various size-patterns are allowed for btst, but not
; included yet. M.Yuhara
(define_insn ""
[
(set (cc0) (and:SI (sign_extend:SI (sign_extend:HI (match_operand:QI 0 "nonimmediate_operand" "rm")))
(match_operand:SI 1 "general_operand" "i")))]
"(GET_CODE (operands
[
1
]
) == CONST_INT
&& (unsigned) INTVAL (operands
[
1
]
) < 0x100
&& exact_log2 (INTVAL (operands
[
1
]
)) >= 0)"
"
*
{
register int log = exact_log2 (INTVAL (operands
[
1
]
));
operands
[
1
]
= gen_rtx (CONST_INT, VOIDmode, log);
return
\"
btst %1,%0.b
\"
;
}")
; I can add more patterns like above. But not yet. M.Yuhara
; mtst is supported only by G/300.
(define_insn ""
[
(set (cc0)
(and:SI (match_operand:SI 0 "general_operand" "%rmi")
(match_operand:SI 1 "general_operand" "rm")))]
"TARGET_G300"
"
*
{
if (GET_CODE (operands
[
0
]
) == CONST_INT)
return
\"
mtst.w %0,%1
\"
;
return
\"
mtst.w %1,%0
\"
;
}")
(define_insn ""
[
(set (cc0)
(and:HI (match_operand:HI 0 "general_operand" "%rmi")
(match_operand:HI 1 "general_operand" "rm")))]
"TARGET_G300"
"
*
{
if (GET_CODE (operands
[
0
]
) == CONST_INT)
return
\"
mtst.h %0,%1
\"
;
return
\"
mtst.h %1,%0
\"
;
}")
(define_insn ""
[
(set (cc0)
(and:QI (match_operand:QI 0 "general_operand" "%rmi")
(match_operand:QI 1 "general_operand" "rm")))]
"TARGET_G300"
"
*
{
if (GET_CODE (operands
[
0
]
) == CONST_INT)
return
\"
mtst.b %0,%1
\"
;
return
\"
mtst.b %1,%0
\"
;
}")
;; move instructions
/
* added by M.Yuhara *
/
;; 1.35.04 89.08.28 modification start
;; register_operand -> general_operand
;; ashift -> mult
(define_insn ""
[
(set (mem:SI (plus:SI
(match_operand:SI 0 "general_operand" "r")
(ashift:SI
(match_operand:SI 1 "general_operand" "r")
(const_int 2))))
(match_operand:SI 2 "general_operand" "rmi"))]
""
"
*
{
return
\"
mov.w %2,@(%0:b,%1
*
4)
\"
;
}")
(define_insn ""
[
(set (mem:SI (plus:SI
(ashift:SI
(match_operand:SI 0 "general_operand" "r")
(const_int 2))
(match_operand:SI 1 "general_operand" "r")))
(match_operand:SI 2 "general_operand" "rmi"))]
""
"
*
{
return
\"
mov.w %2,@(%1:b,%0
*
4)
\"
;
}")
(define_insn ""
[
(set (mem:SI (plus:SI
(match_operand:SI 0 "register_operand" "r")
(mult:SI
(match_operand:SI 1 "register_operand" "r")
(const_int 4))))
(match_operand:SI 2 "general_operand" "rmi"))]
""
"
*
{
return
\"
mov.w %2,@(%0:b,%1
*
4)
\"
;
}")
(define_insn ""
[
(set (mem:SI (plus:SI
(mult:SI
(match_operand:SI 0 "register_operand" "r")
(const_int 4))
(match_operand:SI 1 "register_operand" "r")))
(match_operand:SI 2 "general_operand" "rmi"))]
""
"
*
{
return
\"
mov.w %2,@(%1:b,%0
*
4)
\"
;
}")
(define_insn ""
[
(set (mem:SI (plus:SI
(match_operand:SI 0 "general_operand" "r")
(plus:SI
(match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "register_operand" "i"))))
(match_operand:SI 3 "general_operand" "rmi"))]
""
"
*
{
return
\"
mov.w %3,@(%c2,%0,%1)
\"
;
}")
(define_insn ""
[
(set (mem:SI (plus:SI
(plus:SI
(match_operand:SI 0 "register_operand" "r")
(match_operand:SI 1 "register_operand" "r"))
(match_operand:SI 2 "general_operand" "i")))
(match_operand:SI 3 "general_operand" "rmi"))]
""
"
*
{
return
\"
mov.w %3,@(%c2,%0,%1)
\"
;
}")
(define_insn ""
[
(set (mem:SI (plus:SI
(match_operand:SI 0 "general_operand" "i")
(plus:SI
(match_operand:SI 1 "register_operand" "r")
(mult:SI
(match_operand:SI 2 "register_operand" "r")
(const_int 4)))))
(match_operand:SI 3 "general_operand" "rmi"))]
""
"
*
{
return
\"
mov.w %3,@(%1:b,%0,%2
*
4)
\"
;
}")
;; 89.08.28 1.35.04 modification end
;; Should add "!" to op2 ??
;; General move-address-to-operand should handle these.
;; If that does not work, please figure out why.
;(define_insn ""
;
[
(set (match_operand:SI 0 "push_operand" "=m")
; (plus:SI
; (match_operand:SI 1 "immediate_operand" "i")
; (match_operand:SI 2 "general_operand" "r")))]
; ""
; "mova.w @(%c1,%2),%-")
;(define_insn ""
;
[
(set (match_operand:SI 0 "push_operand" "=m")
; (plus:SI
; (match_operand:SI 1 "general_operand" "r")
; (match_operand:SI 2 "immediate_operand" "i")))]
; ""
; "mova.w @(%c2,%1),%-")
(define_insn ""
[
(set (match_operand:SI 0 "push_operand" "=m")
(minus:SI
(match_operand:SI 1 "general_operand" "r")
(match_operand:SI 2 "immediate_operand" "i")))]
""
"mova.w @(%n2,%1),%-")
;; General case of fullword move.
(define_insn "movsi"
[
(set (match_operand:SI 0 "general_operand" "=rm")
(match_operand:SI 1 "general_operand" "rmi"))]
""
"
*
{
if (GET_CODE (operands
[
1
]
) == CONST_INT)
return mov_imm_word (INTVAL (operands
[
1
]
), operands
[
0
]
);
/
*
if (address_operand (operands
[
1
]
, SImode))
return
\"
mova.w %1,%0
\"
;
*
/
if (push_operand (operands
[
0
]
, SImode))
return
\"
mov.w %1,%-
\"
;
return
\"
mov.w %1,%0
\"
;
}")
/
* pushsi 89.08.10 for test M.Yuhara *
/
/
*
(define_insn ""
[
(set (match_operand:SI 0 "push_operand" "=m")
(match_operand:SI 1 "general_operand" "rmi"))]
""
"
*
{
if (GET_CODE (operands
[
1
]
) == CONST_INT)
return mov_imm_word (INTVAL (operands
[
1
]
), operands
[
0
]
);
if (push_operand (operands
[
0
]
, SImode))
return
\"
mov.w %1,%-
\"
;
return
\"
mov.w %1,%0
\"
;
}")
*
/
(define_insn "movhi"
[
(set (match_operand:HI 0 "general_operand" "=rm")
(match_operand:HI 1 "general_operand" "rmi"))]
""
"
*
{
if (push_operand (operands
[
0
]
, SImode))
return
\"
mov.h %1,%-
\"
;
return
\"
mov.h %1,%0
\"
;
}")
;; Is the operand constraint "+" necessary ????
;; Should I check push_operand ????
(define_insn "movstricthi"
[
(set (strict_low_part (match_operand:HI 0 "general_operand" "+rm"))
(match_operand:HI 1 "general_operand" "rmi"))]
""
"mov.h %1,%0");
(define_insn "movqi"
[
(set (match_operand:QI 0 "general_operand" "=rm")
(match_operand:QI 1 "general_operand" "rmi"))]
""
"
*
{
if (GREG_P (operands
[
0
]
))
{
if (CONSTANT_P (operands
[
1
]
))
return
\"
mov:l %1,%0.w
\"
;
else
return
\"
mov:l %1.b,%0.w
\"
;
}
if (GREG_P (operands
[
1
]
))
return
\"
mov:s %1.w,%0.b
\"
;
return
\"
mov.b %1,%0
\"
;
}")
(define_insn "movstrictqi"
[
(set (strict_low_part (match_operand:QI 0 "general_operand" "+rm"))
(match_operand:QI 1 "general_operand" "rmi"))]
""
"mov.b %1,%0")
(define_insn "movsf"
[
(set (match_operand:SF 0 "general_operand" "=f,mf,rm,fr")
(match_operand:SF 1 "general_operand" "mfF,f,rmF,fr"))]
""
"
*
{
switch (which_alternative)
{
case 0:
if (GET_CODE (operands
[
1
]
) == CONST_DOUBLE)
return output_move_const_single (operands);
return
\"
fmov.s %1,%0
\"
;
case 1:
return
\"
fmov.s %1,%0
\"
;
case 2:
if (GET_CODE (operands
[
1
]
) == CONST_DOUBLE)
return output_move_const_single (operands);
return
\"
mov.w %1,%0
\"
;
case 3:
if (FPU_REG_P (operands
[
0
]
))
return
\"
mov.w %1,%-
\\
n
\\
tfmov.s %+,%0
\"
;
return
\"
fmov.s %1,%-
\\
n
\\
tmov.w %+,%0
\"
;
}
}")
(define_insn "movdf"
[
(set (match_operand:DF 0 "general_operand" "=f,mf,rm,fr")
(match_operand:DF 1 "general_operand" "mfF,f,rmF,fr"))]
""
"
*
{
switch (which_alternative)
{
case 0:
if (GET_CODE (operands
[
1
]
) == CONST_DOUBLE)
return output_move_const_double (operands);
return
\"
fmov.d %1,%0
\"
;
case 1:
return
\"
fmov.d %1,%0
\"
;
case 2:
if (GET_CODE (operands
[
1
]
) == CONST_DOUBLE)
return output_move_const_double (operands);
return output_move_double (operands);
case 3:
if (FPU_REG_P (operands
[
0
]
))
{
rtx xoperands
[
2
]
;
xoperands
[
1
]
= gen_rtx (REG, SImode, REGNO (operands
[
1
]
) + 1);
output_asm_insn (
\"
mov.w %1,%-
\"
, xoperands);
output_asm_insn (
\"
mov.w %1,%-
\"
, operands);
return
\"
fmov.d %+,%0
\"
;
}
else
{
output_asm_insn (
\"
fmov.d %f1,%-
\"
, operands);
output_asm_insn (
\"
mov.w %+,%0
\"
, operands);
operands
[
0
]
= gen_rtx (REG, SImode, REGNO (operands
[
0
]
) + 1);
return
\"
mov.w %+,%0
\"
;
}
}
}")
;; movdi can apply to fp regs in some cases
;; Must check again. you can use fsti/fldi, etc.
;; FPU reg should be included ??
;; 89.12.13 for test
(define_insn "movdi"
;; Let's see if it really still needs to handle fp regs, and, if so, why.
[
(set (match_operand:DI 0 "general_operand" "=rm,&r,&ro")
(match_operand:DI 1 "general_operand" "rF,m,roiF"))]
""
"
*
{
if (FPU_REG_P (operands
[
0
]
))
{
if (FPU_REG_P (operands
[
1
]
))
return
\"
fmov.d %1,%0
\"
;
if (REG_P (operands
[
1
]
))
{
rtx xoperands
[
2
]
;
xoperands
[
1
]
= gen_rtx (REG, SImode, REGNO (operands
[
1
]
) + 1);
output_asm_insn (
\"
mov.w %1,%-
\"
, xoperands);
output_asm_insn (
\"
mov.w %1,%-
\"
, operands);
return
\"
fmov.d %+,%0
\"
;
}
if (GET_CODE (operands
[
1
]
) == CONST_DOUBLE)
return output_move_const_double (operands);
return
\"
fmov.d %f1,%0
\"
;
}
else if (FPU_REG_P (operands
[
1
]
))
{
if (REG_P (operands
[
0
]
))
{
output_asm_insn (
\"
fmov.d %f1,%-
\;
mov.w %+,%0
\"
, operands);
operands
[
0
]
= gen_rtx (REG, SImode, REGNO (operands
[
0
]
) + 1);
return
\"
mov.w %+,%0
\"
;
}
else
return
\"
fmov.d %f1,%0
\"
;
}
return output_move_double (operands);
}
")
;; The definition of this insn does not really explain what it does,
;; but it should suffice
;; that anything generated as this insn will be recognized as one
;; and that it won't successfully combine with anything.
;; This is dangerous when %0 and %1 overlapped !!!!!
;; Ugly code...
(define_insn "movstrhi"
[
(set (match_operand:BLK 0 "general_operand" "=m")
(match_operand:BLK 1 "general_operand" "m"))
(use (match_operand:HI 2 "general_operand" "rmi"))
(clobber (reg:SI 0))
(clobber (reg:SI 1))
(clobber (reg:SI 2))]
""
"
*
{
int op2const;
rtx tmpx;
if (CONSTANT_P (operands
[
1
]
))
{
fprintf (stderr,
\"
smov 1 const err
\"
);
abort ();
}
else if (GET_CODE (operands
[
1
]
) == REG)
{
fprintf (stderr,
\"
smov 1 reg err
\"
);
abort ();
}
else if (GET_CODE (operands
[
1
]
) == MEM)
{
tmpx = XEXP (operands
[
1
]
, 0);
if (CONSTANT_ADDRESS_P (tmpx) || GREG_P (tmpx))
{
operands
[
1
]
= tmpx;
output_asm_insn (
\"
mov.w %1,r0
\"
, operands);
}
else
{
output_asm_insn (
\"
mova %1,r0
\"
, operands);
}
}
else
{
fprintf (stderr,
\"
smov 1 else err
\"
);
abort ();
output_asm_insn (
\"
mova.w %p1,r0
\"
, operands);
}
if (CONSTANT_P (operands
[
0
]
))
{
fprintf (stderr,
\"
smov 0 const err
\"
);
abort ();
}
else if (GET_CODE (operands
[
0
]
) == REG)
{
fprintf (stderr,
\"
smov 0 reg err
\"
);
abort ();
}
else if (GET_CODE (operands
[
0
]
) == MEM)
{
tmpx = XEXP (operands
[
0
]
, 0);
if (CONSTANT_ADDRESS_P (tmpx) || GREG_P (tmpx))
{
operands
[
0
]
= tmpx;
output_asm_insn (
\"
mov.w %0,r1
\"
, operands);
}
else
{
output_asm_insn (
\"
mova %0,r1
\"
, operands);
}
}
else
{
fprintf (stderr,
\"
smov 0 else err
\"
);
abort ();
}
if (GET_CODE (operands
[
2
]
) == CONST_INT)
{
op2const = INTVAL (operands
[
2
]
);
if (op2const % 4 != 0)
{
output_asm_insn (
\"
mov.w %2,r2
\"
, operands);
return
\"
smov/n/f.b
\"
;
}
op2const = op2const / 4;
if (op2const <= 4)
{
if (op2const == 0)
abort (0);
if (op2const == 1)
return
\"
mov.w @r0,@r1
\"
;
output_asm_insn (
\"
mov.w @r0,@r1
\"
, operands);
if (op2const == 2)
return
\"
mov.w @(4,r0),@(4,r1)
\"
;
output_asm_insn (
\"
mov.w @(4,r0),@(4,r1)
\"
, operands);
if (op2const == 3)
return
\"
mov.w @(8,r0),@(8,r1)
\"
;
output_asm_insn (
\"
mov.w @(8,r0),@(8,r1)
\"
, operands);
return
\"
mov.w @(12,r0),@(12,r1)
\"
;
}
operands
[
2
]
=
gen_rtx (CONST_INT, VOIDmode, op2const);
output_asm_insn (
\"
mov.w %2,r2
\"
, operands);
return
\"
smov/n/f.w
\"
;
}
else
{
fprintf (stderr,
\"
smov 0 else err
\"
);
abort ();
output_asm_insn (
\"
mov %2.h,r2.w
\"
, operands);
return
\"
smov/n/f.b
\"
;
}
}")
;; M.Yuhara 89.08.24
;; experiment on the built-in strcpy (__builtin_smov)
;;
;; len = 0 means unknown string length.
;;
;; mem:SI is dummy. Necessary so as not to be deleted by optimization.
;; Use of BLKmode would be better...
;;
;;
(define_insn "smovsi"
[
(set (mem:SI (match_operand:SI 0 "general_operand" "=rm"))
(mem:SI (match_operand:SI 1 "general_operand" "rm")))
(use (match_operand:SI 2 "general_operand" "i"))
(clobber (reg:SI 0))
(clobber (reg:SI 1))
(clobber (reg:SI 2))
(clobber (reg:SI 3))]
""
"
*
{
int len, wlen, blen, offset;
char tmpstr
[
128
]
;
rtx xoperands
[
1
]
;
len = INTVAL (operands
[
2
]
);
output_asm_insn (
\"
mov.w %1,r0
\\
t; begin built-in strcpy
\"
, operands);
output_asm_insn (
\"
mov.w %0,r1
\"
, operands);
if (len == 0)
{
output_asm_insn (
\"
mov:z.w #0,r2
\"
, operands);
output_asm_insn (
\"
mov:z.w #0,r3
\"
, operands);
return
\"
smov/eq/f.b
\\
t; end built-in strcpy
\"
;
}
wlen = len / 4;
blen = len - wlen
*
4;
if (wlen > 0)
{
if (len <= 40 && !TARGET_FORCE_SMOV)
{
output_asm_insn (
\"
mov.w @r0,@r1
\"
, operands);
offset = 4;
while ( (blen = len - offset) > 0)
{
if (blen >= 4)
{
sprintf (tmpstr,
\"
mov.w @(%d,r0),@(%d,r1)
\"
,
offset, offset);
output_asm_insn (tmpstr, operands);
offset += 4;
}
else if (blen >= 2)
{
sprintf (tmpstr,
\"
mov.h @(%d,r0),@(%d,r1)
\"
,
offset, offset);
output_asm_insn (tmpstr, operands);
offset += 2;
}
else
{
sprintf (tmpstr,
\"
mov.b @(%d,r0),@(%d,r1)
\"
,
offset, offset);
output_asm_insn (tmpstr, operands);
offset++;
}
}
return
\"\\
t
\\
t; end built-in strcpy
\"
;
}
else
{
xoperands
[
0
]
= gen_rtx (CONST_INT, VOIDmode, wlen);
output_asm_insn (
\"
mov.w %0,r2
\"
, xoperands);
output_asm_insn (
\"
smov/n/f.w
\"
, operands);
}
}
if (blen >= 2)
{
output_asm_insn (
\"
mov.h @r0,@r1
\"
, operands);
if (blen == 3)
output_asm_insn (
\"
mov.b @(2,r0),@(2,r1)
\"
, operands);
}
else if (blen == 1)
{
output_asm_insn (
\"
mov.b @r0,@r1
\"
, operands);
}
return
\"\\
t
\\
t; end built-in strcpy
\"
;
}")
;; truncation instructions
(define_insn "truncsiqi2"
[
(set (match_operand:QI 0 "general_operand" "=rm")
(truncate:QI
(match_operand:SI 1 "general_operand" "rmi")))]
""
"mov %1.w,%0.b")
; "
*
;{
; if (GET_CODE (operands
[
0
]
) == REG)
; return
\"
mov.w %1,%0
\"
;
; if (GET_CODE (operands
[
1
]
) == MEM)
; operands
[
1
]
= adj_offsettable_operand (operands
[
1
]
, 3);
; return
\"
mov.b %1,%0
\"
;
;}")
(define_insn "trunchiqi2"
[
(set (match_operand:QI 0 "general_operand" "=rm")
(truncate:QI
(match_operand:HI 1 "general_operand" "rmi")))]
""
"mov %1.h,%0.b")
; "
*
;{
; if (GET_CODE (operands
[
0
]
) == REG)
; return
\"
mov.h %1,%0
\"
;
; if (GET_CODE (operands
[
1
]
) == MEM)
; operands
[
1
]
= adj_offsettable_operand (operands
[
1
]
, 1);
; return
\"
mov.b %1,%0
\"
;
;}")
(define_insn "truncsihi2"
[
(set (match_operand:HI 0 "general_operand" "=rm")
(truncate:HI
(match_operand:SI 1 "general_operand" "rmi")))]
""
"mov %1.w,%0.h")
; "
*
;{
; if (GET_CODE (operands
[
0
]
) == REG)
; return
\"
mov.w %1,%0
\"
;
; if (GET_CODE (operands
[
1
]
) == MEM)
; operands
[
1
]
= adj_offsettable_operand (operands
[
1
]
, 2);
; return
\"
mov.h %1,%0
\"
;
;}")
;; zero extension instructions
;; define_expand (68k) -> define_insn (Gmicro)
(define_insn "zero_extendhisi2"
[
(set (match_operand:SI 0 "general_operand" "=rm")
(zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
""
"movu %1.h,%0.w")
(define_insn "zero_extendqihi2"
[
(set (match_operand:HI 0 "general_operand" "=rm")
(zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
""
"movu %1.b,%0.h")
(define_insn "zero_extendqisi2"
[
(set (match_operand:SI 0 "general_operand" "=rm")
(zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
""
"movu %1.b,%0.w")
;; sign extension instructions
(define_insn "extendhisi2"
[
(set (match_operand:SI 0 "general_operand" "=rm")
(sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
""
"mov %1.h,%0.w")
(define_insn "extendqihi2"
[
(set (match_operand:HI 0 "general_operand" "=rm")
(sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
""
"mov %1.b,%0.h")
(define_insn "extendqisi2"
[
(set (match_operand:SI 0 "general_operand" "=rm")
(sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
""
"mov %1.b,%0.w")
;; Conversions between float and double.
(define_insn "extendsfdf2"
[
(set (match_operand:DF 0 "general_operand" "=
*
frm,f")
(float_extend:DF
(match_operand:SF 1 "general_operand" "f,rmF")))]
"TARGET_FPU"
"
*
{
if (FPU_REG_P (operands
[
0
]
))
{
if (GET_CODE (operands
[
1
]
) == CONST_DOUBLE)
return output_move_const_double (operands);
if (GREG_P (operands
[
1
]
))
{
output_asm_insn (
\"
mov.w %1,%-
\"
, operands);
return
\"
fmov %+.s,%0.d
\"
;
}
return
\"
fmov %1.s,%0.d
\"
;
}
else
{
if (GREG_P (operands
[
0
]
))
{
output_asm_insn (
\"
fmov %1.s,%-.d
\"
, operands);
output_asm_insn (
\"
mov.w %+,%0
\"
, operands);
operands
[
0
]
= gen_rtx (REG, SImode, REGNO (operands
[
0
]
) + 1);
return
\"
mov.w %+,%0
\"
;
}
return
\"
fmov %1.s,%0.d
\"
;
}
}")
(define_insn "truncdfsf2"
[
(set (match_operand:SF 0 "general_operand" "=rfm")
(float_truncate:SF
(match_operand:DF 1 "general_operand" "f")))]
"TARGET_FPU"
"
*
{
if (GREG_P (operands
[
0
]
))
{
output_asm_insn (
\"
fmov %1.d,%-.s
\"
, operands);
return
\"
mov.w %+,%0
\"
;
}
return
\"
fmov %1.d,%0.s
\"
;
}")
;; Conversion between fixed point and floating point.
;; Note that among the fix-to-float insns
;; the ones that start with SImode come first.
;; That is so that an operand that is a CONST_INT
;; (and therefore lacks a specific machine mode).
;; will be recognized as SImode (which is always valid)
;; rather than as QImode or HImode.
(define_insn "floatsisf2"
[
(set (match_operand:SF 0 "general_operand" "=f")
(float:SF (match_operand:SI 1 "general_operand" "rmi")))]
"TARGET_FPU"
"fldi %1.w,%0.s")
(define_insn "floatsidf2"
[
(set (match_operand:DF 0 "general_operand" "=f")
(float:DF (match_operand:SI 1 "general_operand" "rmi")))]
"TARGET_FPU"
"fldi %1.w,%0.d")
(define_insn "floathisf2"
[
(set (match_operand:SF 0 "general_operand" "=f")
(float:SF (match_operand:HI 1 "general_operand" "rmi")))]
"TARGET_FPU"
"fldi %1.h,%0.s")
(define_insn "floathidf2"
[
(set (match_operand:DF 0 "general_operand" "=f")
(float:DF (match_operand:HI 1 "general_operand" "rmi")))]
"TARGET_FPU"
"fldi %1.h,%0.d")
(define_insn "floatqisf2"
[
(set (match_operand:SF 0 "general_operand" "=f")
(float:SF (match_operand:QI 1 "general_operand" "rmi")))]
"TARGET_FPU"
"fldi %1.b,%0.s")
(define_insn "floatqidf2"
[
(set (match_operand:DF 0 "general_operand" "=f")
(float:DF (match_operand:QI 1 "general_operand" "rmi")))]
"TARGET_FPU"
"fldi %1.b,%0.d")
;;; Convert a float to a float whose value is an integer.
;;; This is the first stage of converting it to an integer type.
;
;(define_insn "ftruncdf2"
;
[
(set (match_operand:DF 0 "general_operand" "=f")
; (fix:DF (match_operand:DF 1 "general_operand" "fFm")))]
; "TARGET_FPU"
; "
*
;{
; return
\"
fintrz.d %f1,%0
\"
;
;}")
;
;(define_insn "ftruncsf2"
;
[
(set (match_operand:SF 0 "general_operand" "=f")
; (fix:SF (match_operand:SF 1 "general_operand" "fFm")))]
; "TARGET_FPU"
; "
*
;{
; return
\"
fintrz.s %f1,%0
\"
;
;}")
;; Convert a float to an integer.
(define_insn "fix_truncsfqi2"
[
(set (match_operand:QI 0 "general_operand" "=rm")
(fix:QI (fix:SF (match_operand:SF 1 "general_operand" "f"))))]
"TARGET_FPU"
"fsti %1.s,%0.b")
(define_insn "fix_truncsfhi2"
[
(set (match_operand:HI 0 "general_operand" "=rm")
(fix:HI (fix:SF (match_operand:SF 1 "general_operand" "f"))))]
"TARGET_FPU"
"fsti %1.s,%0.h")
(define_insn "fix_truncsfsi2"
[
(set (match_operand:SI 0 "general_operand" "=rm")
(fix:SI (fix:SF (match_operand:SF 1 "general_operand" "f"))))]
"TARGET_FPU"
"fsti %1.s,%0.w")
(define_insn "fix_truncdfqi2"
[
(set (match_operand:QI 0 "general_operand" "=rm")
(fix:QI (fix:DF (match_operand:DF 1 "general_operand" "f"))))]
"TARGET_FPU"
"fsti %1.d,%0.b")
(define_insn "fix_truncdfhi2"
[
(set (match_operand:HI 0 "general_operand" "=rm")
(fix:HI (fix:DF (match_operand:DF 1 "general_operand" "f"))))]
"TARGET_FPU"
"fsti %1.d,%0.h")
(define_insn "fix_truncdfsi2"
[
(set (match_operand:SI 0 "general_operand" "=rm")
(fix:SI (fix:DF (match_operand:DF 1 "general_operand" "f"))))]
"TARGET_FPU"
"fsti %1.d,%0.w")
;;; Special add patterns
;;; 89.09.28
;; This should be redundant; please find out why regular addsi3
;; fails to match this case.
;(define_insn ""
;
[
(set (mem:SI (plus:SI
; (plus:SI (match_operand 0 "general_operand" "r")
; (match_operand 1 "general_operand" "r"))
; (match_operand 2 "general_operand" "i")))
; (plus:SI
; (mem:SI (plus:SI
; (plus:SI (match_dup 0)
; (match_dup 1))
; (match_dup 2)))
; (match_operand 3 "general_operand" "rmi")))]
; ""
; "add.w %3,@(%c2,%0,%1)")
;; add instructions
;; Note that the last two alternatives are near-duplicates
;; in order to handle insns generated by reload.
;; This is needed since they are not themselves reloaded,
;; so commutativity won't apply to them.
(define_insn "addsi3"
[
(set (match_operand:SI 0 "general_operand" "=rm,!r,!r")
(plus:SI (match_operand:SI 1 "general_operand" "%0,r,ri")
(match_operand:SI 2 "general_operand" "rmi,ri,r")))]
""
"
*
{
if (which_alternative == 0)
{
if (GET_CODE (operands
[
2
]
) == CONST_INT)
{
operands
[
1
]
= operands
[
2
]
;
return add_imm_word (INTVAL (operands
[
1
]
), operands
[
0
]
,
&operands[1]);
}
else
return
\"
add.w %2,%0
\"
;
}
else
{
if (GET_CODE (operands
[
1
]
) == REG
&& REGNO (operands
[
0
]
) == REGNO (operands
[
1
]
))
return
\"
add.w %2,%0
\"
;
if (GET_CODE (operands
[
2
]
) == REG
&& REGNO (operands
[
0
]
) == REGNO (operands
[
2
]
))
return
\"
add.w %1,%0
\"
;
if (GET_CODE (operands[1]) == REG)
{
if (GET_CODE (operands[2]) == REG)
return \"mova.w @(%1,%2),%0\";
else
return \"mova.w @(%c2,%1),%0\";
}
else
return \"mova.w @(%c1,%2),%0\";
}
}")
(define_insn ""
[
(set (match_operand:SI 0 "general_operand" "=rm")
(plus:SI (match_operand:SI 1 "general_operand" "0")
(sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "rmi"))))]
""
"
*
{
if (CONSTANT_P (operands
[
2
]
))
{
operands
[
1
]
= operands
[
2
]
;
return add_imm_word (INTVAL (operands
[
1
]
), operands
[
0
]
,
&operands[1]);
}
else
return
\"
add %2.h,%0.w
\"
;
}")
(define_insn "addhi3"
[
(set (match_operand:HI 0 "general_operand" "=rm")
(plus:HI (match_operand:HI 1 "general_operand" "%0")
(match_operand:HI 2 "general_operand" "rmi")))]
""
"
*
{
if (GET_CODE (operands
[
2
]
) == CONST_INT
&& INTVAL (operands
[
2
]
) < 0)
return
\"
sub.h #%n2,%0
\"
;
if (GREG_P (operands
[
0
]
))
{
if (CONSTANT_P (operands
[
2
]
))
return
\"
add:l %2,%0.w
\"
;
else
return
\"
add:l %2.h,%0.w
\"
;
}
return
\"
add.h %2,%0
\"
;
}")
(define_insn ""
[
(set (strict_low_part (match_operand:HI 0 "general_operand" "+rm"))
(plus:HI (match_dup 0)
(match_operand:HI 1 "general_operand" "rmi")))]
""
"add.h %1,%0")
(define_insn "addqi3"
[
(set (match_operand:QI 0 "general_operand" "=rm")
(plus:QI (match_operand:QI 1 "general_operand" "%0")
(match_operand:QI 2 "general_operand" "rmi")))]
""
"
*
{
if (GET_CODE (operands
[
2
]
) == CONST_INT
&& INTVAL (operands
[
2
]
) < 0)
return
\"
sub.b #%n2,%0
\"
;
if (GREG_P (operands
[
0
]
))
{
if (CONSTANT_P (operands
[
2
]
))
return
\"
add:l %2,%0.w
\"
;
else
return
\"
add:l %2.b,%0.w
\"
;
}
return
\"
add.b %2,%0
\"
;
}")
(define_insn ""
[
(set (strict_low_part (match_operand:QI 0 "general_operand" "+rm"))
(plus:QI (match_dup 0)
(match_operand:QI 1 "general_operand" "rmi")))]
""
"add.b %1,%0")
(define_insn "adddf3"
[
(set (match_operand:DF 0 "general_operand" "=f")
(plus:DF (match_operand:DF 1 "general_operand" "%0")
(match_operand:DF 2 "general_operand" "fmG")))]
"TARGET_FPU"
"fadd.d %f2,%0")
(define_insn "addsf3"
[
(set (match_operand:SF 0 "general_operand" "=f")
(plus:SF (match_operand:SF 1 "general_operand" "%0")
(match_operand:SF 2 "general_operand" "fmG")))]
"TARGET_FPU"
"fadd.s %f2,%0")
;; subtract instructions
(define_insn "subsi3"
[
(set (match_operand:SI 0 "general_operand" "=rm,!r")
(minus:SI (match_operand:SI 1 "general_operand" "0,r")
(match_operand:SI 2 "general_operand" "rmi,i")))]
""
"
*
{
if (which_alternative == 0
|| (GET_CODE (operands
[
1
]
) == REG
&& REGNO (operands
[
0
]
) == REGNO (operands
[
1
]
)))
{
if (GET_CODE (operands
[
2
]
) == CONST_INT)
{
operands
[
1
]
= operands
[
2
]
;
return sub_imm_word (INTVAL (operands
[
1
]
),
operands
[
0
]
,
&operands[1]);
}
else
return
\"
sub.w %2,%0
\"
;
}
else
return
\"
mova.w @(%n2,%1),%0
\"
;
}")
(define_insn ""
[
(set (match_operand:SI 0 "general_operand" "=rm")
(minus:SI (match_operand:SI 1 "general_operand" "0")
(sign_extend:SI (match_operand:HI 2 "nonimmediate_operand" "rmi"))))]
""
"sub %2.h,%0.w")
(define_insn "subhi3"
[
(set (match_operand:HI 0 "general_operand" "=rm")
(minus:HI (match_operand:HI 1 "general_operand" "0")
(match_operand:HI 2 "general_operand" "rmi")))]
""
"
*
{
if (GET_CODE (operands
[
2
]
) == CONST_INT
&& INTVAL (operands
[
2
]
) < 0
&& INTVAL (operands
[
2
]
) != 0x8000)
return
\"
add.h #%n2,%0
\"
;
return
\"
sub.h %2,%0
\"
;
}")
(define_insn ""
[
(set (strict_low_part (match_operand:HI 0 "general_operand" "+rm"))
(minus:HI (match_dup 0)
(match_operand:HI 1 "general_operand" "rmi")))]
""
"sub.h %1,%0")
(define_insn "subqi3"
[
(set (match_operand:QI 0 "general_operand" "=rm")
(minus:QI (match_operand:QI 1 "general_operand" "0")
(match_operand:QI 2 "general_operand" "rmi")))]
""
"
*
{
if (GET_CODE (operands
[
2
]
) == CONST_INT
&& INTVAL (operands
[
2
]
) < 0
&& INTVAL (operands
[
2
]
) != 0x80)
return
\"
add.b #%n2,%0
\"
;
return
\"
sub.b %2,%0
\"
;
}")
(define_insn ""
[
(set (strict_low_part (match_operand:QI 0 "general_operand" "+rm"))
(minus:QI (match_dup 0)
(match_operand:QI 1 "general_operand" "rmi")))]
""
"sub.b %1,%0")
(define_insn "subdf3"
[
(set (match_operand:DF 0 "general_operand" "=f")
(minus:DF (match_operand:DF 1 "general_operand" "0")
(match_operand:DF 2 "general_operand" "fmG")))]
"TARGET_FPU"
"fsub.d %f2,%0")
(define_insn "subsf3"
[
(set (match_operand:SF 0 "general_operand" "=f")
(minus:SF (match_operand:SF 1 "general_operand" "0")
(match_operand:SF 2 "general_operand" "fmG")))]
"TARGET_FPU"
"fsub.s %f2,%0")
;; multiply instructions
(define_insn "mulqi3"
[
(set (match_operand:QI 0 "general_operand" "=rm")
(mult:QI (match_operand:QI 1 "general_operand" "%0")
(match_operand:QI 2 "general_operand" "rmi")))]
""
"mul.b %2,%0")
(define_insn "mulhi3"
[
(set (match_operand:HI 0 "general_operand" "=rm")
(mult:HI (match_operand:HI 1 "general_operand" "%0")
(match_operand:HI 2 "general_operand" "rmi")))]
""
"mul.h %2,%0")
;; define_insn "mulhisi3"
(define_insn "mulsi3"
[
(set (match_operand:SI 0 "general_operand" "=rm")
(mult:SI (match_operand:SI 1 "general_operand" "%0")
(match_operand:SI 2 "general_operand" "rmi")))]
""
"mul.w %2,%0")
(define_insn "muldf3"
[
(set (match_operand:DF 0 "general_operand" "=f")
(mult:DF (match_operand:DF 1 "general_operand" "%0")
(match_operand:DF 2 "general_operand" "fmG")))]
"TARGET_FPU"
"fmul.d %f2,%0")
(define_insn "mulsf3"
[
(set (match_operand:SF 0 "general_operand" "=f")
(mult:SF (match_operand:SF 1 "general_operand" "%0")
(match_operand:SF 2 "general_operand" "fmG")))]
"TARGET_FPU"
"fmul.s %f2,%0")
;; divide instructions
(define_insn "divqi3"
[
(set (match_operand:QI 0 "general_operand" "=rm")
(div:QI (match_operand:QI 1 "general_operand" "0")
(match_operand:QI 2 "general_operand" "rmi")))]
""
"div.b %2,%0")
(define_insn "divhi3"
[
(set (match_operand:HI 0 "general_operand" "=rm")
(div:HI (match_operand:HI 1 "general_operand" "0")
(match_operand:HI 2 "general_operand" "rmi")))]
""
"div.h %2,%0")
(define_insn "divhisi3"
[
(set (match_operand:HI 0 "general_operand" "=r")
(div:HI (match_operand:SI 1 "general_operand" "0")
(match_operand:HI 2 "general_operand" "rmi")))]
""
"div %2.h,%0.w")
(define_insn "divsi3"
[
(set (match_operand:SI 0 "general_operand" "=rm")
(div:SI (match_operand:SI 1 "general_operand" "0")
(match_operand:SI 2 "general_operand" "rmi")))]
""
"div.w %2,%0")
(define_insn "udivqi3"
[
(set (match_operand:QI 0 "general_operand" "=rm")
(udiv:QI (match_operand:QI 1 "general_operand" "0")
(match_operand:QI 2 "general_operand" "rmi")))]
""
"divu.b %2,%0")
(define_insn "udivhi3"
[
(set (match_operand:HI 0 "general_operand" "=rm")
(udiv:HI (match_operand:HI 1 "general_operand" "0")
(match_operand:HI 2 "general_operand" "rmi")))]
""
"divu.h %2,%0")
(define_insn "udivhisi3"
[
(set (match_operand:HI 0 "general_operand" "=r")
(udiv:HI (match_operand:SI 1 "general_operand" "0")
(match_operand:HI 2 "general_operand" "rmi")))]
""
"divu %2.h,%0.w")
(define_insn "udivsi3"
[
(set (match_operand:SI 0 "general_operand" "=rm")
(udiv:SI (match_operand:SI 1 "general_operand" "0")
(match_operand:SI 2 "general_operand" "rmi")))]
""
"divu.w %2,%0")
(define_insn "divdf3"
[
(set (match_operand:DF 0 "general_operand" "=f")
(div:DF (match_operand:DF 1 "general_operand" "0")
(match_operand:DF 2 "general_operand" "fmG")))]
"TARGET_FPU"
"fdiv.d %f2,%0")
(define_insn "divsf3"
[
(set (match_operand:SF 0 "general_operand" "=f")
(div:SF (match_operand:SF 1 "general_operand" "0")
(match_operand:SF 2 "general_operand" "fmG")))]
"TARGET_FPU"
"fdiv.s %f2,%0")
;; Remainder instructions.
(define_insn "modqi3"
[
(set (match_operand:QI 0 "general_operand" "=rm")
(mod:QI (match_operand:QI 1 "general_operand" "0")
(match_operand:QI 2 "general_operand" "rmi")))]
""
"rem.b %2,%0")
(define_insn "modhisi3"
[
(set (match_operand:HI 0 "general_operand" "=r")
(mod:HI (match_operand:SI 1 "general_operand" "0")
(match_operand:HI 2 "general_operand" "rmi")))]
""
"rem.h %2,%0")
(define_insn "umodqi3"
[
(set (match_operand:QI 0 "general_operand" "=rm")
(umod:QI (match_operand:QI 1 "general_operand" "0")
(match_operand:QI 2 "general_operand" "rmi")))]
""
"remu.b %2,%0")
(define_insn "umodhi3"
[
(set (match_operand:HI 0 "general_operand" "=rm")
(umod:HI (match_operand:HI 1 "general_operand" "0")
(match_operand:HI 2 "general_operand" "rmi")))]
""
"remu.h %2,%0")
(define_insn "umodhisi3"
[
(set (match_operand:HI 0 "general_operand" "=r")
(umod:HI (match_operand:SI 1 "general_operand" "0")
(match_operand:HI 2 "general_operand" "rmi")))]
""
"remu %2.h,%0.w")
;; define_insn "divmodsi4"
(define_insn "udivmodsi4"
[
(set (match_operand:SI 0 "general_operand" "=rm")
(udiv:SI (match_operand:SI 1 "general_operand" "0")
(match_operand:SI 2 "general_operand" "rmi")))
(set (match_operand:SI 3 "general_operand" "=r")
(umod:SI (match_dup 1) (match_dup 2)))]
""
"mov.w #0,%3;divx.w %2,%0,%3")
;; logical-and instructions
(define_insn "andsi3"
[
(set (match_operand:SI 0 "general_operand" "=rm")
(and:SI (match_operand:SI 1 "general_operand" "%0")
(match_operand:SI 2 "general_operand" "rmi")))]
""
"
*
{
if (GET_CODE (operands
[
2
]
) == CONST_INT
&& (INTVAL (operands
[
2
]
) | 0xffff) == 0xffffffff
&& (GREG_P (operands
[
0
]
)
|| offsettable_memref_p (operands
[
0
]
)))
{
if (GET_CODE (operands
[
0
]
) != REG)
operands
[
0
]
= adj_offsettable_operand (operands
[
0
]
, 2);
operands
[
2
]
= gen_rtx (CONST_INT, VOIDmode,
INTVAL (operands
[
2
]
) & 0xffff);
/
* Do not delete a following tstl %0 insn; that would be incorrect. *
/
CC_STATUS_INIT;
return
\"
and.h %2,%0
\"
;
}
return
\"
and.w %2,%0
\"
;
}")
(define_insn "andhi3"
[
(set (match_operand:HI 0 "general_operand" "=rm")
(and:HI (match_operand:HI 1 "general_operand" "%0")
(match_operand:HI 2 "general_operand" "rmi")))]
""
"and.h %2,%0")
(define_insn "andqi3"
[
(set (match_operand:QI 0 "general_operand" "=rm")
(and:QI (match_operand:QI 1 "general_operand" "%0")
(match_operand:QI 2 "general_operand" "rmi")))]
""
"and.b %2,%0")
(define_insn ""
[
(set (match_operand:SI 0 "general_operand" "=r")
(and:SI (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm"))
(match_operand:SI 2 "general_operand" "0")))]
""
"
*
{
if (GET_CODE (operands
[
1
]
) == CONST_INT)
return
\"
and %1,%0.w
\"
;
return
\"
and %1.h,%0.w
\"
;
}")
(define_insn ""
[
(set (match_operand:SI 0 "general_operand" "=r")
(and:SI (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "rm"))
(match_operand:SI 2 "general_operand" "0")))]
""
"
*
{
if (GET_CODE (operands
[
1
]
) == CONST_INT)
return
\"
and %1,%0.w
\"
;
return
\"
and %1.b,%0.w
\"
;
}")
;; inclusive-or instructions
(define_insn "iorsi3"
[
(set (match_operand:SI 0 "general_operand" "=rm")
(ior:SI (match_operand:SI 1 "general_operand" "%0")
(match_operand:SI 2 "general_operand" "rmi")))]
""
"
*
{
register int logval;
if (GET_CODE (operands
[
2
]
) == CONST_INT
&& INTVAL (operands
[
2
]
) >> 16 == 0
&& (GREG_P (operands
[
0
]
)
|| offsettable_memref_p (operands
[
0
]
)))
{
if (GET_CODE (operands
[
0
]
) != REG)
operands
[
0
]
= adj_offsettable_operand (operands
[
0
]
, 2);
/
* Do not delete a following tstl %0 insn; that would be incorrect. *
/
CC_STATUS_INIT;
return
\"
or.h %2,%0
\"
;
}
if (GET_CODE (operands
[
2
]
) == CONST_INT
&& (logval = exact_log2 (INTVAL (operands
[
2
]
))) >= 0
&& (GREG_P (operands
[
0
]
)
|| offsettable_memref_p (operands
[
0
]
)))
{
if (GREG_P (operands
[
0
]
))
{
if (logval < 7)
{
operands
[
1
]
= gen_rtx (CONST_INT, VOIDmode, 7 - logval);
return
\"
bset.b %1,%0
\"
;
}
operands
[
1
]
= gen_rtx (CONST_INT, VOIDmode, 31 - logval);
return
\"
bset.w %1,%0
\"
;
}
else
{
operands
[
0
]
= adj_offsettable_operand (operands
[
0
]
, 3 - (logval / 8));
operands
[
1
]
= gen_rtx (CONST_INT, VOIDmode, 7 - (logval % 8));
}
return
\"
bset.b %1,%0
\"
;
}
return
\"
or.w %2,%0
\"
;
}")
(define_insn "iorhi3"
[
(set (match_operand:HI 0 "general_operand" "=rm")
(ior:HI (match_operand:HI 1 "general_operand" "%0")
(match_operand:HI 2 "general_operand" "rmi")))]
""
"or.h %2,%0")
(define_insn "iorqi3"
[
(set (match_operand:QI 0 "general_operand" "=rm")
(ior:QI (match_operand:QI 1 "general_operand" "%0")
(match_operand:QI 2 "general_operand" "rmi")))]
""
"or.b %2,%0")
;; xor instructions
(define_insn "xorsi3"
[
(set (match_operand:SI 0 "general_operand" "=rm")
(xor:SI (match_operand:SI 1 "general_operand" "%0")
(match_operand:SI 2 "general_operand" "rmi")))]
""
"
*
{
if (GET_CODE (operands
[
2
]
) == CONST_INT
&& INTVAL (operands
[
2
]
) >> 16 == 0
&& (offsettable_memref_p (operands
[
0
]
) || GREG_P (operands
[
0
]
)))
{
if (! GREG_P (operands
[
0
]
))
operands
[
0
]
= adj_offsettable_operand (operands
[
0
]
, 2);
/
* Do not delete a following tstl %0 insn; that would be incorrect. *
/
CC_STATUS_INIT;
return
\"
xor.h %2,%0
\"
;
}
return
\"
xor.w %2,%0
\"
;
}")
(define_insn "xorhi3"
[
(set (match_operand:HI 0 "general_operand" "=rm")
(xor:HI (match_operand:HI 1 "general_operand" "%0")
(match_operand:HI 2 "general_operand" "rmi")))]
""
"xor.h %2,%0")
(define_insn "xorqi3"
[
(set (match_operand:QI 0 "general_operand" "=rm")
(xor:QI (match_operand:QI 1 "general_operand" "%0")
(match_operand:QI 2 "general_operand" "rmi")))]
""
"xor.b %2,%0")
;; negation instructions
(define_insn "negsi2"
[
(set (match_operand:SI 0 "general_operand" "=rm")
(neg:SI (match_operand:SI 1 "general_operand" "0")))]
""
"neg.w %0")
(define_insn "neghi2"
[
(set (match_operand:HI 0 "general_operand" "=rm")
(neg:HI (match_operand:HI 1 "general_operand" "0")))]
""
"neg.h %0")
(define_insn "negqi2"
[
(set (match_operand:QI 0 "general_operand" "=rm")
(neg:QI (match_operand:QI 1 "general_operand" "0")))]
""
"neg.b %0")
(define_insn "negsf2"
[
(set (match_operand:SF 0 "general_operand" "f")
(neg:SF (match_operand:SF 1 "general_operand" "fmF")))]
"TARGET_FPU"
"fneg.s %f1,%0")
(define_insn "negdf2"
[
(set (match_operand:DF 0 "general_operand" "f")
(neg:DF (match_operand:DF 1 "general_operand" "fmF")))]
"TARGET_FPU"
"fneg.d %f1,%0")
;; Absolute value instructions
(define_insn "abssf2"
[
(set (match_operand:SF 0 "general_operand" "f")
(abs:SF (match_operand:SF 1 "general_operand" "fmF")))]
"TARGET_FPU"
"fabs.s %f1,%0")
(define_insn "absdf2"
[
(set (match_operand:DF 0 "general_operand" "f")
(abs:DF (match_operand:DF 1 "general_operand" "fmF")))]
"TARGET_FPU"
"fabs.d %f1,%0")
;; one complement instructions
(define_insn "one_cmplsi2"
[
(set (match_operand:SI 0 "general_operand" "=rm")
(not:SI (match_operand:SI 1 "general_operand" "0")))]
""
"not.w %0")
(define_insn "one_cmplhi2"
[
(set (match_operand:HI 0 "general_operand" "=rm")
(not:HI (match_operand:HI 1 "general_operand" "0")))]
""
"not.h %0")
(define_insn "one_cmplqi2"
[
(set (match_operand:QI 0 "general_operand" "=rm")
(not:QI (match_operand:QI 1 "general_operand" "0")))]
""
"not.b %0")
;; Optimized special case of shifting.
;; Must precede the general case.
(define_insn ""
[
(set (match_operand:SI 0 "general_operand" "=r")
(ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
(const_int 24)))]
"GET_CODE (XEXP (operands
[
1
]
, 0)) != POST_INC
&& GET_CODE (XEXP (operands
[
1
]
, 0)) != PRE_DEC"
"mov:l %1.b,%0.w")
(define_insn ""
[
(set (match_operand:SI 0 "general_operand" "=r")
(lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
(const_int 24)))]
"GET_CODE (XEXP (operands
[
1
]
, 0)) != POST_INC
&& GET_CODE (XEXP (operands
[
1
]
, 0)) != PRE_DEC"
"movu %1.b,%0.w")
(define_insn ""
[
(set (cc0) (compare (match_operand:QI 0 "general_operand" "i")
(lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
(const_int 24))))]
"(GET_CODE (operands
[
0
]
) == CONST_INT
&& (INTVAL (operands
[
0
]
) & ~0xff) == 0)"
"
*
{
cc_status.flags |= CC_REVERSED;
if (my_signed_comp (insn))
return
\"
cmp.b %0,%1
\"
;
return
\"
cmpu.b %0,%1
\"
;
}")
(define_insn ""
[
(set (cc0) (compare (lshiftrt:SI (match_operand:SI 0 "memory_operand" "m")
(const_int 24))
(match_operand:QI 1 "general_operand" "i")))]
"(GET_CODE (operands
[
1
]
) == CONST_INT
&& (INTVAL (operands
[
1
]
) & ~0xff) == 0)"
"
*
if (my_signed_comp (insn))
return
\"
cmp.b %1,%0
\"
;
return
\"
cmpu.b %1,%0
\"
;
")
(define_insn ""
[
(set (cc0) (compare (match_operand:QI 0 "general_operand" "i")
(ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
(const_int 24))))]
"(GET_CODE (operands
[
0
]
) == CONST_INT
&& ((INTVAL (operands
[
0
]
) + 0x80) & ~0xff) == 0)"
"
*
cc_status.flags |= CC_REVERSED;
if (my_signed_comp (insn))
return
\"
cmp.b %0,%1
\"
;
return
\"
cmpu.b %0,%1
\"
;
")
(define_insn ""
[
(set (cc0) (compare (ashiftrt:SI (match_operand:SI 0 "memory_operand" "m")
(const_int 24))
(match_operand:QI 1 "general_operand" "i")))]
"(GET_CODE (operands
[
1
]
) == CONST_INT
&& ((INTVAL (operands
[
1
]
) + 0x80) & ~0xff) == 0)"
"
*
if (my_signed_comp (insn))
return
\"
cmp.b %1,%0
\"
;
return
\"
cmpu.b %1,%0
\"
;
")
;; arithmetic shift instructions
;; We don't need the shift memory by 1 bit instruction
(define_insn "ashlsi3"
[
(set (match_operand:SI 0 "general_operand" "=rm")
(ashift:SI (match_operand:SI 1 "general_operand" "0")
(match_operand:SI 2 "general_operand" "rmi")))]
""
"sha.w %2,%0")
(define_insn "ashlhi3"
[
(set (match_operand:HI 0 "general_operand" "=rm")
(ashift:HI (match_operand:HI 1 "general_operand" "0")
(match_operand:HI 2 "general_operand" "rmi")))]
""
"sha.h %2,%0")
(define_insn "ashlqi3"
[
(set (match_operand:QI 0 "general_operand" "=rm")
(ashift:QI (match_operand:QI 1 "general_operand" "0")
(match_operand:QI 2 "general_operand" "rmi")))]
""
"sha.b %2,%0")
;; Arithmetic right shift on the Gmicro works by negating the shift count
;; ashiftrt -> ashift
(define_expand "ashrsi3"
[
(set (match_operand:SI 0 "general_operand" "=rm")
(ashift:SI (match_operand:SI 1 "general_operand" "0")
(match_operand:SI 2 "general_operand" "rmi")))]
""
"{ operands
[
2
]
= negate_rtx (SImode, operands
[
2
]
); }")
;; ashiftrt -> ashift
(define_expand "ashrhi3"
[
(set (match_operand:HI 0 "general_operand" "=rm")
(ashift:HI (match_operand:HI 1 "general_operand" "0")
(match_operand:HI 2 "general_operand" "rmi")))]
""
" { operands
[
2
]
= negate_rtx (HImode, operands
[
2
]
); }")
;; ashiftrt -> ashift
(define_expand "ashrqi3"
[
(set (match_operand:QI 0 "general_operand" "=rm")
(ashift:QI (match_operand:QI 1 "general_operand" "0")
(match_operand:QI 2 "general_operand" "rmi")))]
""
" { operands
[
2
]
= negate_rtx (QImode, operands
[
2
]
); }")
;; logical shift instructions
(define_insn "lshlsi3"
[
(set (match_operand:SI 0 "general_operand" "=rm")
(lshift:SI (match_operand:SI 1 "general_operand" "0")
(match_operand:SI 2 "general_operand" "rmi")))]
""
"shl.w %2,%0")
(define_insn "lshlhi3"
[
(set (match_operand:HI 0 "general_operand" "=rm")
(lshift:HI (match_operand:HI 1 "general_operand" "0")
(match_operand:HI 2 "general_operand" "rmi")))]
""
"shl.h %2,%0")
(define_insn "lshlqi3"
[
(set (match_operand:QI 0 "general_operand" "=rm")
(lshift:QI (match_operand:QI 1 "general_operand" "0")
(match_operand:QI 2 "general_operand" "rmi")))]
""
"shl.b %2,%0")
;; lshiftrt -> lshift
(define_expand "lshrsi3"
[
(set (match_operand:SI 0 "general_operand" "=rm")
(lshift:SI (match_operand:SI 1 "general_operand" "0")
(match_operand:SI 2 "general_operand" "rmi")))]
""
" { operands
[
2
]
= negate_rtx (SImode, operands
[
2
]
); }")
;; lshiftrt -> lshift
(define_expand "lshrhi3"
[
(set (match_operand:HI 0 "general_operand" "=rm")
(lshift:HI (match_operand:HI 1 "general_operand" "0")
(match_operand:HI 2 "general_operand" "rmi")))]
""
" { operands
[
2
]
= negate_rtx (HImode, operands
[
2
]
); }")
;; lshiftrt -> lshift
(define_expand "lshrqi3"
[
(set (match_operand:QI 0 "general_operand" "=rm")
(lshift:QI (match_operand:QI 1 "general_operand" "0")
(match_operand:QI 2 "general_operand" "rmi")))]
""
" { operands
[
2
]
= negate_rtx (QImode, operands
[
2
]
); }")
;; rotate instructions
(define_insn "rotlsi3"
[
(set (match_operand:SI 0 "general_operand" "=rm")
(rotate:SI (match_operand:SI 1 "general_operand" "0")
(match_operand:SI 2 "general_operand" "rmi")))]
""
"rol.w %2,%0")
(define_insn "rotlhi3"
[
(set (match_operand:HI 0 "general_operand" "=rm")
(rotate:HI (match_operand:HI 1 "general_operand" "0")
(match_operand:HI 2 "general_operand" "rmi")))]
""
"rol.h %2,%0")
(define_insn "rotlqi3"
[
(set (match_operand:QI 0 "general_operand" "=rm")
(rotate:QI (match_operand:QI 1 "general_operand" "0")
(match_operand:QI 2 "general_operand" "rmi")))]
""
"rol.b %2,%0")
(define_expand "rotrsi3"
[
(set (match_operand:SI 0 "general_operand" "=rm")
(rotatert:SI (match_operand:SI 1 "general_operand" "0")
(match_operand:SI 2 "general_operand" "rmi")))]
""
" { operands
[
2
]
= negate_rtx (SImode, operands
[
2
]
); }")
(define_expand "rotrhi3"
[
(set (match_operand:HI 0 "general_operand" "=rm")
(rotatert:HI (match_operand:HI 1 "general_operand" "0")
(match_operand:HI 2 "general_operand" "rmi")))]
""
" { operands
[
2
]
= negate_rtx (HImode, operands
[
2
]
); }")
(define_expand "rotrqi3"
[
(set (match_operand:QI 0 "general_operand" "=rm")
(rotatert:QI (match_operand:QI 1 "general_operand" "0")
(match_operand:QI 2 "general_operand" "rmi")))]
""
" { operands
[
2
]
= negate_rtx (QImode, operands
[
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.
;; Should I add mode_dependent_address_p ????
(define_insn ""
[
(set (zero_extract:SI (match_operand:SI 0 "nonimmediate_operand" "+rm")
(match_operand:SI 1 "immediate_operand" "i")
(match_operand:SI 2 "immediate_operand" "i"))
(match_operand:SI 3 "general_operand" "rm"))]
"TARGET_BITFIELD
&& GET_CODE (operands
[
1
]
) == CONST_INT
&& (INTVAL (operands
[
1
]
) == 8 || INTVAL (operands
[
1
]
) == 16)
&& GET_CODE (operands
[
2
]
) == CONST_INT
&& INTVAL (operands
[
2
]
) % INTVAL (operands
[
1
]
) == 0
&& (GET_CODE (operands
[
0
]
) != REG
|| ( INTVAL (operands
[
1
]
) + INTVAL (operands
[
2
]
) == 32))"
"
*
{
if (GET_CODE (operands
[
3
]
) == MEM)
operands
[
3
]
= adj_offsettable_operand (operands
[
3
]
,
(32 - INTVAL (operands
[
1
]
)) / 8);
if (GET_CODE (operands
[
0
]
) == REG)
{
if (INTVAL (operands
[
1
]
) == 8)
return
\"
movu %3.b,%0.w
\"
;
return
\"
movu %3.h,%0.w
\"
;
}
else
{
operands
[
0
]
= adj_offsettable_operand (operands
[
0
]
, INTVAL (operands
[
2
]
) / 8);
if (INTVAL (operands
[
1
]
) == 8)
return
\"
mov.b %3,%0
\"
;
return
\"
mov.h %3,%0
\"
;
}
}")
(define_insn ""
[
(set (match_operand:SI 0 "general_operand" "=&r")
(zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
(match_operand:SI 2 "immediate_operand" "i")
(match_operand:SI 3 "immediate_operand" "i")))]
"TARGET_BITFIELD
&& GET_CODE (operands
[
2
]
) == CONST_INT
&& (INTVAL (operands
[
2
]
) == 8 || INTVAL (operands
[
2
]
) == 16)
&& GET_CODE (operands
[
3
]
) == CONST_INT
&& INTVAL (operands
[
3
]
) % INTVAL (operands
[
2
]
) == 0"
"
*
{
if (!REG_P (operands
[
1
]
))
operands
[
1
]
= adj_offsettable_operand (operands
[
1
]
, INTVAL (operands
[
3
]
) / 8);
if (REG_P (operands
[
0
]
))
{
if (REG_P (operands
[
1
]
))
{
if (INTVAL (operands
[
2
]
) == 8)
{ /
* width == 8 *
/
switch (INTVAL (operands
[
3
]
))
{
case 0:
return
\"
mov.w %1,%0;shl.w #-24,%0
\"
;
break;
case 8:
return
\"
mov.w %1,%0;shl.w #8,%0;shl.w #-24,%0
\"
;
break;
case 16:
return
\"
mov.w %1,%0;shl.w #16,%0;shl.w #-24,%0
\"
;
break;
case 24:
return
\"
movu %1.b,%0.w
\"
;
break;
default:
myabort (2);
}
}
else
{
switch (INTVAL (operands
[
3
]
))
{
case 0:
return
\"
mov.w %1,%0;shl.w #-16,%0
\"
;
break;
case 16:
return
\"
movu %1.h,%0.w
\"
;
break;
default:
myabort (3);
}
}
}
else
{
if (INTVAL (operands
[
2
]
) == 8)
return
\"
movu %1.h,%0.w
\"
;
else
return
\"
movu %1.b,%0.w
\"
;
}
}
else
{ /
* op[0] == MEM *
/
if (INTVAL (operands
[
2
]
) == 8)
return
\"
movu %1.b,%0.w
\"
;
return
\"
movu %1.h,%0.w
\"
;
}
}")
(define_insn ""
[
(set (match_operand:SI 0 "general_operand" "=r")
(sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "ro")
(match_operand:SI 2 "immediate_operand" "i")
(match_operand:SI 3 "immediate_operand" "i")))]
"TARGET_BITFIELD
&& GET_CODE (operands
[
2
]
) == CONST_INT
&& (INTVAL (operands
[
2
]
) == 8 || INTVAL (operands
[
2
]
) == 16)
&& GET_CODE (operands
[
3
]
) == CONST_INT
&& INTVAL (operands
[
3
]
) % INTVAL (operands
[
2
]
) == 0"
"
*
{
if (!REG_P (operands
[
1
]
))
operands
[
1
]
= adj_offsettable_operand (operands
[
1
]
, INTVAL (operands
[
3
]
) / 8);
if (REG_P (operands
[
0
]
))
{
if (REG_P (operands
[
1
]
))
{
if (INTVAL (operands
[
2
]
) == 8)
{ /
* width == 8 *
/
switch (INTVAL (operands
[
3
]
))
{
case 0:
return
\"
mov.w %1,%0;sha.w #-24,%0
\"
;
break;
case 8:
return
\"
mov.w %1,%0;shl.w #8,%0;sha.w #-24,%0
\"
;
break;
case 16:
return
\"
mov.w %1,%0;shl.w #16,%0;sha.w #-24,%0
\"
;
break;
case 24:
return
\"
mov %1.b,%0.w
\"
;
break;
default:
myabort (4);
}
}
else
{
switch (INTVAL (operands
[
3
]
))
{
case 0:
return
\"
mov.w %1,%0;sha.w #-16,%0
\"
;
break;
case 16:
return
\"
mov %1.h,%0.w
\"
;
break;
default:
myabort (5);
}
}
}
else
{
if (INTVAL (operands
[
2
]
) == 8)
return
\"
mov %1.h,%0.w
\"
;
else
return
\"
mov %1.b,%0.w
\"
;
}
}
else
{ /
* op[0] == MEM *
/
if (INTVAL (operands
[
2
]
) == 8)
return
\"
mov %1.b,%0.w
\"
;
return
\"
mov %1.h,%0.w
\"
;
}
}")
;; Bit field instructions, general cases.
;; "o,d" constraint causes a nonoffsettable memref to match the "o"
;; so that its address is reloaded.
;; extv dest:SI src(:QI/:SI) width:SI pos:SI
;; r.w m r.w/# rmi
;; %0 %1 %2 %3
(define_insn "extv"
[
(set (match_operand:SI 0 "general_operand" "=r")
(sign_extract:SI (match_operand:QI 1 "nonimmediate_operand" "m")
(match_operand:SI 2 "general_operand" "ri")
(match_operand:SI 3 "general_operand" "rmi")))]
"TARGET_BITFIELD"
"bfext %3,%2,%1,%0")
(define_insn "extzv"
[
(set (match_operand:SI 0 "general_operand" "=r")
(zero_extract:SI (match_operand:QI 1 "nonimmediate_operand" "m")
(match_operand:SI 2 "general_operand" "ri")
(match_operand:SI 3 "general_operand" "rmi")))]
"TARGET_BITFIELD"
"bfextu %3,%2,%1,%0")
;; There is no insn on the Gmicro to NOT/SET/CLR bitfield.
;; insv dest(BF):QI/SI width:SI pos:SI src:SI
;; m r.w rmi r.w/i
;; 0 1 2 3
(define_insn "insv"
[
(set (zero_extract:SI (match_operand:QI 0 "nonimmediate_operand" "+m,m")
(match_operand:SI 1 "general_operand" "r,i")
(match_operand:SI 2 "general_operand" "rmi,i"))
(match_operand:SI 3 "general_operand" "ri,ri"))]
"TARGET_BITFIELD"
"bfinsu %3,%2,%1,%0")
;;; bfins/bfinsu ????????
;; == == == == == == == == == == == == ==
;; Now recognize bit field insns that operate on registers
;; (or at least were intended to do so).
;; On the Gmicro/300,
;; bitfield instructions are not applicable to registers ;-<
;; But I write the register cases, because without them the gcc
;; seems to use "and" instruction with some other instructions
;; instead of using a shift instruction.
;; It is because on many processors shift instructions are slower.
;; On the Gmicro/300 which has a barrel shifter,
;; it is faster to use a shift instruction.
;;
;; Restricts width and offset to be immediates.
;;
(define_insn ""
[
(set (match_operand:SI 0 "general_operand" "=r")
(sign_extract:SI (match_operand:SI 1 "nonimmediate_operand" "r")
(match_operand:SI 2 "immediate_operand" "i")
(match_operand:SI 3 "immediate_operand" "i")))]
"TARGET_BITFIELD"
"
*
{
if (REGNO (operands
[
0
]
) != REGNO (operands
[
1
]
))
output_asm_insn (
\"
mov.w %1,%0
\"
, operands);
if (INTVAL (operands
[
3
]
) != 0)
output_asm_insn (
\"
shl.w %3,%0
\"
, operands);
operands
[
2
]
= gen_rtx (CONST_INT, VOIDmode, -(32 - INTVAL (operands
[
2
]
)));
return
\"
sha.w %3,%0
\"
;
}")
(define_insn ""
[
(set (match_operand:SI 0 "general_operand" "=r")
(zero_extract:SI (match_operand:SI 1 "nonimmediate_operand" "r")
(match_operand:SI 2 "immediate_operand" "i")
(match_operand:SI 3 "immediate_operand" "i")))]
"TARGET_BITFIELD"
"
*
{
if (REGNO (operands
[
0
]
) != REGNO (operands
[
1
]
))
output_asm_insn (
\"
mov.w %1,%0
\"
, operands);
if (INTVAL (operands
[
3
]
) != 0)
output_asm_insn (
\"
shl.w %3,%0
\"
, operands);
operands
[
2
]
= gen_rtx (CONST_INT, VOIDmode, -(32 - INTVAL (operands
[
2
]
)));
return
\"
shl.w %3,%0
\"
;
}")
;; There are more descriptions for m68k, but not yet for the Gmicro.
;;
;; Basic conditional jump instructions.
(define_insn "beq"
[
(set (pc)
(if_then_else (eq (cc0)
(const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
""
"
*
{
OUTPUT_JUMP (
\"
beq %b0
\"
,
\"
fbeq %b0
\"
,
\"
beq %b0
\"
);
}")
(define_insn "bne"
[
(set (pc)
(if_then_else (ne (cc0)
(const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
""
"
*
{
OUTPUT_JUMP (
\"
bne %b0
\"
,
\"
fbne %b0
\"
,
\"
bne %b0
\"
);
}")
(define_insn "bgt"
[
(set (pc)
(if_then_else (gt (cc0)
(const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
""
"
*
OUTPUT_JUMP (
\"
bgt %b0
\"
,
\"
fbgt %b0
\"
, 0);
")
(define_insn "bgtu"
[
(set (pc)
(if_then_else (gtu (cc0)
(const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
""
"bgt %b0")
(define_insn "blt"
[
(set (pc)
(if_then_else (lt (cc0)
(const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
""
"
*
OUTPUT_JUMP (
\"
blt %b0
\"
,
\"
fblt %b0
\"
,
\"
bms %b0
\"
);
")
;; bms ?????
;;
(define_insn "bltu"
[
(set (pc)
(if_then_else (ltu (cc0)
(const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
""
"blt %b0")
(define_insn "bge"
[
(set (pc)
(if_then_else (ge (cc0)
(const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
""
"
*
OUTPUT_JUMP (
\"
bge %b0
\"
,
\"
fbge %b0
\"
,
\"
bmc %b0
\"
);
")
;; bmc ??
(define_insn "bgeu"
[
(set (pc)
(if_then_else (geu (cc0)
(const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
""
"bge %b0")
(define_insn "ble"
[
(set (pc)
(if_then_else (le (cc0)
(const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
""
"ble %b0")
(define_insn "bleu"
[
(set (pc)
(if_then_else (leu (cc0)
(const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
""
"ble %b0")
;; Negated conditional jump instructions.
(define_insn ""
[
(set (pc)
(if_then_else (eq (cc0)
(const_int 0))
(pc)
(label_ref (match_operand 0 "" ""))))]
""
"
*
{
OUTPUT_JUMP (
\"
bne %b0
\"
,
\"
fbne %b0
\"
,
\"
bne %b0
\"
);
}")
(define_insn ""
[
(set (pc)
(if_then_else (ne (cc0)
(const_int 0))
(pc)
(label_ref (match_operand 0 "" ""))))]
""
"
*
{
OUTPUT_JUMP (
\"
beq %b0
\"
,
\"
fbeq %b0
\"
,
\"
beq %b0
\"
);
}")
(define_insn ""
[
(set (pc)
(if_then_else (gt (cc0)
(const_int 0))
(pc)
(label_ref (match_operand 0 "" ""))))]
""
"
*
OUTPUT_JUMP (
\"
ble %b0
\"
,
\"
fbngt %b0
\"
, 0);
")
;; fbngt ???
(define_insn ""
[
(set (pc)
(if_then_else (gtu (cc0)
(const_int 0))
(pc)
(label_ref (match_operand 0 "" ""))))]
""
"ble %b0")
(define_insn ""
[
(set (pc)
(if_then_else (lt (cc0)
(const_int 0))
(pc)
(label_ref (match_operand 0 "" ""))))]
""
"
*
OUTPUT_JUMP (
\"
bge %b0
\"
,
\"
fbnlt %b0
\"
,
\"
jbmc %b0
\"
);
")
(define_insn ""
[
(set (pc)
(if_then_else (ltu (cc0)
(const_int 0))
(pc)
(label_ref (match_operand 0 "" ""))))]
""
"blt %b0")
(define_insn ""
[
(set (pc)
(if_then_else (ge (cc0)
(const_int 0))
(pc)
(label_ref (match_operand 0 "" ""))))]
""
"
*
OUTPUT_JUMP (
\"
blt %b0
\"
,
\"
fbnge %b0
\"
,
\"
jbms %b0
\"
);
")
(define_insn ""
[
(set (pc)
(if_then_else (geu (cc0)
(const_int 0))
(pc)
(label_ref (match_operand 0 "" ""))))]
""
"blt %b0")
;; ????
(define_insn ""
[
(set (pc)
(if_then_else (le (cc0)
(const_int 0))
(pc)
(label_ref (match_operand 0 "" ""))))]
""
"
*
OUTPUT_JUMP (
\"
bgt %b0
\"
,
\"
fbnle %b0
\"
, 0);
")
(define_insn ""
[
(set (pc)
(if_then_else (leu (cc0)
(const_int 0))
(pc)
(label_ref (match_operand 0 "" ""))))]
""
"bgt %b0")
;; Unconditional and other jump instructions
(define_insn "jump"
[
(set (pc)
(label_ref (match_operand 0 "" "")))]
""
"bra %b0")
(define_insn "tablejump"
[
(set (pc)
(plus:SI (pc) (match_operand:SI 0 "general_operand" "r")))
(use (label_ref (match_operand 1 "" "")))]
""
"jmp @(pc:b,4:4,%0)")
;;
;; Should Add code for "ACB", "SCB". !!! ????
;; See m68k.h (dbra)
;;
;; Call subroutine with no return value.
(define_insn "call"
[
(call (match_operand:QI 0 "general_operand" "m")
(match_operand:SI 1 "general_operand" "rmi"))]
;; Operand 1 not really used on the Gmicro.
""
"
*
{
if (GET_CODE (operands
[
0
]
) == MEM
&& GET_CODE (XEXP (operands
[
0
]
,0)) == SYMBOL_REF)
return
\"
bsr %b0
\"
;
return
\"
jsr %0
\"
;
}")
;; Call subroutine, returning value in operand 0
;; (which must be a hard register).
(define_insn "call_value"
[
(set (match_operand 0 "" "=rf")
(call (match_operand:QI 1 "general_operand" "m")
(match_operand:SI 2 "general_operand" "rmi")))]
;; Operand 2 not really used on the Gmicro.
""
"
*
{
if (GET_CODE (operands
[
1
]
) == MEM
&& GET_CODE (XEXP (operands
[
1
]
,0)) == SYMBOL_REF)
return
\"
bsr %b1
\"
;
return
\"
jsr %1
\"
;
}")
(define_insn "nop"
[
(const_int 0)
]
""
"nop")
;; Turned off because the general move-an-address pattern handles it.
;;
;; Thus goes after the move instructions
;; because the move instructions are better (require no spilling)
;; when they can apply.
;; After add/sub now !!
;(define_insn "pushasi"
;
[
(set (match_operand:SI 0 "push_operand" "=m")
; (match_operand:SI 1 "address_operand" "p"))]
; ""
; "
*
;{
; if (GET_CODE (operands
[
1
]
) == CONST_INT)
; return push_imm_word (INTVAL (operands
[
1
]
), operands
[
0
]
);
; if (CONSTANT_P (operands
[
1
]
))
; return
\"
mov.w %1,%-
\"
;
; if (GET_CODE (operands
[
1
]
) == REG)
; return
\"
mov.w %1,%-
\"
;
; else if (GET_CODE (operands
[
1
]
) == MEM)
; {
; return
\"
mov.w %1,%-
\"
;
; }
; else
; return
\"
mova.w %p1,%-
\"
;
;}")
;; This should not be used unless the add/sub insns can't be.
/
* mova.[whq] 89.08.11 for test M.Yuhara *
/
;(define_insn ""
;
[
(set (match_operand:SI 0 "general_operand" "=rm")
; (address (match_operand:SI 1 "address_operand" "p")))]
; ""
; "
*
;{
; if (GET_CODE (operands
[
1
]
) == CONST_INT)
; return mov_imm_word (INTVAL (operands
[
1
]
), operands
[
0
]
);
; if (CONSTANT_P (operands
[
1
]
))
; return
\"
mov.w %1,%0
\"
;
; if (GET_CODE (operands
[
1
]
) == REG)
; return
\"
mov.w %1,%0
\"
;
; else if (GET_CODE (operands
[
1
]
) == MEM) {
; operands
[
1
]
= XEXP (operands
[
1
]
,0);
; return
\"
mov.w %1,%0
\"
;
; }
; else
; return
\"
mova.w %p1,%0
\"
;
;}")
(define_insn ""
[
(set (match_operand:SI 0 "general_operand" "=rm")
(address (match_operand:HI 1 "address_operand" "")))]
""
"
*
{
if (GET_CODE (operands
[
1
]
) == CONST_INT)
return mov_imm_word (INTVAL (operands
[
1
]
), operands
[
0
]
);
if (CONSTANT_P (operands
[
1
]
))
return
\"
mov.w %1,%0
\"
;
if (GET_CODE (operands
[
1
]
) == REG)
return
\"
mov.w %1,%0
\"
;
else if (GET_CODE (operands
[
1
]
) == MEM)
{
operands
[
1
]
= XEXP (operands
[
1
]
,0);
return
\"
mov.w %1,%0
\"
; /
* OK ? *
/
}
else
return
\"
mova.w %p1,%0
\"
;
}")
;(define_insn ""
;
[
(set (match_operand:SI 0 "general_operand" "=rm")
; (match_operand:QI 1 "address_operand" "p"))]
; ""
; "
*
;{
; if (push_operand (operands
[
0
]
, SImode))
; return
\"
mova %1,%-
\"
;
; return
\"
mova %1,%0
\"
;
;}")
;(define_insn ""
;
[
(set (match_operand:SI 0 "general_operand" "=rm")
; (match_operand:QI 1 "address_operand" "p"))]
; ""
; "
*
;{
; if (CONSTANT_P (operands
[
1
]
))
; return
\"
mov.w %1,%0
\"
;
; else if (GET_CODE (operands
[
1
]
) == REG)
; return
\"
mov.w %1,%0
\"
;
; else if (GET_CODE (operands
[
1
]
) == MEM)
; {
; operands
[
1
]
= XEXP (operands
[
1
]
,0);
; return
\"
mov.w %1,%0 ; OK?
\"
;
; }
; else if (GET_CODE (operands
[
0
]
) == REG
; && GET_CODE (operands
[
1
]
) == PLUS)
; {
; rtx xreg, xdisp;
;
; if (GET_CODE (XEXP (operands
[
1
]
, 0)) == REG
; && REGNO (XEXP (operands
[
1
]
, 0)) == REGNO (operands
[
0
]
))
; {
; xreg = XEXP (operands
[
1
]
, 0);
; xdisp = XEXP (operands
[
1
]
,1);
; }
; else
; {
; xreg = XEXP (operands
[
1
]
, 1);
; xdisp = XEXP (operands
[
1
]
,0);
; }
;
; if (GET_CODE (xreg) == REG
; && REGNO (xreg) == REGNO (operands
[
0
]
)
; && (CONSTANT_P (xdisp) || GET_CODE (xdisp) == REG))
; {
; operands
[
1
]
= xdisp;
; if (CONSTANT_P (xdisp))
; return add_imm_word (INTVAL (xdisp), xreg,
&operands[1]);
; else
; return
\"
add.w %1,%0
\"
;
; }
; }
; return
\"
mova.w %p1,%0
\"
;
;}")
;; This is the first machine-dependent peephole optimization.
;; It is useful when a floating value is returned from a function call
;; and then is moved into an FP register.
;; But it is mainly intended to test the support for these optimizations.
(define_peephole
[
(set (reg:SI 15) (plus:SI (reg:SI 15) (const_int 4)))
(set (match_operand:DF 0 "register_operand" "f")
(match_operand:DF 1 "register_operand" "r"))]
"FPU_REG_P (operands
[
0
]
) && ! FPU_REG_P (operands
[
1
]
)"
"
*
{
rtx xoperands
[
2
]
;
xoperands
[
1
]
= gen_rtx (REG, SImode, REGNO (operands
[
1
]
) + 1);
output_asm_insn (
\"
mov.w %1,@sp
\"
, xoperands);
output_asm_insn (
\"
mov.w %1,%-
\"
, operands);
return
\"
fmov.d %+,%0
\"
;
}
")
;;- Local variables:
;;- mode:emacs-lisp
;;- comment-start: ";;- "
;;- comment-start-skip: ";+-
*
"
;;- 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:
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment