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
66954a38
Commit
66954a38
authored
Jan 08, 1992
by
Charles Hannum
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
entered into RCS
From-SVN: r172
parent
7d0e3dd4
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
1115 additions
and
0 deletions
+1115
-0
gcc/config/spur/spur.md
+1115
-0
No files found.
gcc/config/spur/spur.md
0 → 100644
View file @
66954a38
;;- Machine description for SPUR chip for GNU C compiler
;; Copyright (C) 1988 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.
;; 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.
;;- See file "rtl.def" for documentation on define_insn, match_
*
, et. al.
;;- cpp macro #define NOTICE_UPDATE_CC in file tm.h handles condition code
;;- updates for most instructions.
;;- Operand classes for the register allocator:
;; Compare instructions.
;; This pattern is used for generating an "insn"
;; which does just a compare and sets a (fictitious) condition code.
;; The actual SPUR insns are compare-and-conditional-jump.
;; The define_peephole's below recognize the combinations of
;; compares and jumps, and output each pair as a single assembler insn.
;; This controls RTL generation and register allocation.
(define_insn "cmpsi"
[
(set (cc0)
(compare (match_operand:SI 0 "register_operand" "rK")
(match_operand:SI 1 "nonmemory_operand" "rK")))]
""
"
*
{
cc_status.value1 = operands
[
0
]
, cc_status.value2 = operands
[
1
]
;
return
\"\"
;
}")
;; We have to have this because cse can optimize the previous pattern
;; into this one.
(define_insn "tstsi"
[
(set (cc0)
(match_operand:SI 0 "register_operand" "r"))]
""
"
*
{
cc_status.value1 = operands
[
0
]
, cc_status.value2 = const0_rtx;
return
\"\"
;
}")
;; These control RTL generation for conditional jump insns
;; and match them for register allocation.
(define_insn "beq"
[
(set (pc)
(if_then_else (eq (cc0)
(const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
""
"
*
return output_compare (operands,
\"
eq
\"
,
\"
eq
\"
,
\"
ne
\"
,
\"
ne
\"
); ")
(define_insn "bne"
[
(set (pc)
(if_then_else (ne (cc0)
(const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
""
"
*
return output_compare (operands,
\"
ne
\"
,
\"
ne
\"
,
\"
eq
\"
,
\"
eq
\"
); ")
(define_insn "bgt"
[
(set (pc)
(if_then_else (gt (cc0)
(const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
""
"
*
return output_compare (operands,
\"
gt
\"
,
\"
lt
\"
,
\"
le
\"
,
\"
ge
\"
); ")
(define_insn "bgtu"
[
(set (pc)
(if_then_else (gtu (cc0)
(const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
""
"
*
return output_compare (operands,
\"
ugt
\"
,
\"
ult
\"
,
\"
ule
\"
,
\"
uge
\"
); ")
(define_insn "blt"
[
(set (pc)
(if_then_else (lt (cc0)
(const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
""
"
*
return output_compare (operands,
\"
lt
\"
,
\"
gt
\"
,
\"
ge
\"
,
\"
le
\"
); ")
(define_insn "bltu"
[
(set (pc)
(if_then_else (ltu (cc0)
(const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
""
"
*
return output_compare (operands,
\"
ult
\"
,
\"
ugt
\"
,
\"
uge
\"
,
\"
ule
\"
); ")
(define_insn "bge"
[
(set (pc)
(if_then_else (ge (cc0)
(const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
""
"
*
return output_compare (operands,
\"
ge
\"
,
\"
le
\"
,
\"
lt
\"
,
\"
gt
\"
); ")
(define_insn "bgeu"
[
(set (pc)
(if_then_else (geu (cc0)
(const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
""
"
*
return output_compare (operands,
\"
uge
\"
,
\"
ule
\"
,
\"
ult
\"
,
\"
ugt
\"
); ")
(define_insn "ble"
[
(set (pc)
(if_then_else (le (cc0)
(const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
""
"
*
return output_compare (operands,
\"
le
\"
,
\"
ge
\"
,
\"
gt
\"
,
\"
lt
\"
); ")
(define_insn "bleu"
[
(set (pc)
(if_then_else (leu (cc0)
(const_int 0))
(label_ref (match_operand 0 "" ""))
(pc)))]
""
"
*
return output_compare (operands,
\"
ule
\"
,
\"
uge
\"
,
\"
ugt
\"
,
\"
ult
\"
); ")
;; These match inverted jump insns for register allocation.
(define_insn ""
[
(set (pc)
(if_then_else (eq (cc0)
(const_int 0))
(pc)
(label_ref (match_operand 0 "" ""))))]
""
"
*
return output_compare (operands,
\"
ne
\"
,
\"
ne
\"
,
\"
eq
\"
,
\"
eq
\"
); ")
(define_insn ""
[
(set (pc)
(if_then_else (ne (cc0)
(const_int 0))
(pc)
(label_ref (match_operand 0 "" ""))))]
""
"
*
return output_compare (operands,
\"
eq
\"
,
\"
eq
\"
,
\"
ne
\"
,
\"
ne
\"
); ")
(define_insn ""
[
(set (pc)
(if_then_else (gt (cc0)
(const_int 0))
(pc)
(label_ref (match_operand 0 "" ""))))]
""
"
*
return output_compare (operands,
\"
le
\"
,
\"
ge
\"
,
\"
gt
\"
,
\"
lt
\"
); ")
(define_insn ""
[
(set (pc)
(if_then_else (gtu (cc0)
(const_int 0))
(pc)
(label_ref (match_operand 0 "" ""))))]
""
"
*
return output_compare (operands,
\"
ule
\"
,
\"
uge
\"
,
\"
ugt
\"
,
\"
ult
\"
); ")
(define_insn ""
[
(set (pc)
(if_then_else (lt (cc0)
(const_int 0))
(pc)
(label_ref (match_operand 0 "" ""))))]
""
"
*
return output_compare (operands,
\"
ge
\"
,
\"
le
\"
,
\"
lt
\"
,
\"
gt
\"
); ")
(define_insn ""
[
(set (pc)
(if_then_else (ltu (cc0)
(const_int 0))
(pc)
(label_ref (match_operand 0 "" ""))))]
""
"
*
return output_compare (operands,
\"
uge
\"
,
\"
ule
\"
,
\"
ult
\"
,
\"
ugt
\"
); ")
(define_insn ""
[
(set (pc)
(if_then_else (ge (cc0)
(const_int 0))
(pc)
(label_ref (match_operand 0 "" ""))))]
""
"
*
return output_compare (operands,
\"
lt
\"
,
\"
gt
\"
,
\"
ge
\"
,
\"
le
\"
); ")
(define_insn ""
[
(set (pc)
(if_then_else (geu (cc0)
(const_int 0))
(pc)
(label_ref (match_operand 0 "" ""))))]
""
"
*
return output_compare (operands,
\"
ult
\"
,
\"
ugt
\"
,
\"
uge
\"
,
\"
ule
\"
); ")
(define_insn ""
[
(set (pc)
(if_then_else (le (cc0)
(const_int 0))
(pc)
(label_ref (match_operand 0 "" ""))))]
""
"
*
return output_compare (operands,
\"
gt
\"
,
\"
lt
\"
,
\"
le
\"
,
\"
ge
\"
); ")
(define_insn ""
[
(set (pc)
(if_then_else (leu (cc0)
(const_int 0))
(pc)
(label_ref (match_operand 0 "" ""))))]
""
"
*
return output_compare (operands,
\"
ugt
\"
,
\"
ult
\"
,
\"
ule
\"
,
\"
uge
\"
); ")
;; Move instructions
(define_insn "movsi"
[
(set (match_operand:SI 0 "general_operand" "=r,m")
(match_operand:SI 1 "general_operand" "rmi,rJ"))]
""
"
*
{
if (GET_CODE (operands
[
0
]
) == MEM)
return
\"
st_32 %r1,%0
\"
;
if (GET_CODE (operands
[
1
]
) == MEM)
return
\"
ld_32 %0,%1
\;
nop
\"
;
if (GET_CODE (operands
[
1
]
) == REG)
return
\"
add_nt %0,%1,$0
\"
;
if (GET_CODE (operands
[
1
]
) == SYMBOL_REF && operands
[
1
]
->unchanging)
return
\"
add_nt %0,r24,$(%1-0b)
\"
;
return
\"
add_nt %0,r0,%1
\"
;
}")
(define_insn ""
[
(set (match_operand:SI 0 "register_operand" "=r")
(mem:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "register_operand" "r"))))]
""
"ld_32 %0,%1,%2
\;
nop")
;; Generate insns for moving single bytes.
(define_expand "movqi"
[
(set (match_operand:QI 0 "general_operand" "")
(match_operand:QI 1 "general_operand" ""))]
""
"
{
if (GET_CODE (operands
[
0
]
) == MEM && GET_CODE (operands
[
1
]
) == MEM)
operands
[
1
]
= copy_to_reg (operands
[
1
]
);
if (GET_CODE (operands
[
1
]
) == MEM)
{
rtx tem = gen_reg_rtx (SImode);
rtx addr = force_reg (SImode, XEXP (operands
[
1
]
, 0));
rtx subreg;
emit_move_insn (tem, gen_rtx (MEM, SImode, addr));
if (GET_CODE (operands[0]) == SUBREG)
subreg = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[0]),
SUBREG_WORD (operands[0]));
else
subreg = gen_rtx (SUBREG, SImode, operands[0], 0);
emit_insn (gen_rtx (SET, VOIDmode, subreg,
gen_rtx (ZERO_EXTRACT, SImode, tem,
gen_rtx (CONST_INT, VOIDmode, 8),
addr)));
}
else if (GET_CODE (operands
[
0
]
) == MEM)
{
rtx tem = gen_reg_rtx (SImode);
rtx addr = force_reg (SImode, XEXP (operands
[
0
]
, 0));
rtx subreg;
emit_move_insn (tem, gen_rtx (MEM, SImode, addr));
if (! CONSTANT_ADDRESS_P (operands[1]))
{
if (GET_CODE (operands[1]) == SUBREG)
subreg = gen_rtx (SUBREG, SImode, SUBREG_REG (operands[1]),
SUBREG_WORD (operands[1]));
else
subreg = gen_rtx (SUBREG, SImode, operands[1], 0);
}
emit_insn (gen_rtx (SET, VOIDmode,
gen_rtx (ZERO_EXTRACT, SImode, tem,
gen_rtx (CONST_INT, VOIDmode, 8),
addr),
subreg));
emit_move_insn (gen_rtx (MEM, SImode, addr), tem);
}
else
{
emit_insn (gen_rtx (SET, VOIDmode, operands
[
0
]
, operands
[
1
]
));
}
DONE;
}")
;; Recognize insns generated for moving single bytes.
(define_insn ""
[
(set (match_operand:QI 0 "general_operand" "=r,m")
(match_operand:QI 1 "general_operand" "rmi,r"))]
""
"
*
{
if (GET_CODE (operands
[
0
]
) == MEM)
return
\"
st_32 %1,%0
\"
;
if (GET_CODE (operands
[
1
]
) == MEM)
return
\"
ld_32 %0,%1
\;
nop
\"
;
if (GET_CODE (operands
[
1
]
) == REG)
return
\"
add_nt %0,%1,$0
\"
;
return
\"
add_nt %0,r0,%1
\"
;
}")
(define_insn ""
[
(set (match_operand:SI 0 "register_operand" "=r")
(zero_extract:SI (match_operand:SI 1 "register_operand" "r")
(const_int 8)
(match_operand:SI 2 "nonmemory_operand" "rI")))]
""
"extract %0,%1,%2")
(define_insn ""
[
(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
(const_int 8)
(match_operand:SI 1 "nonmemory_operand" "rI"))
(match_operand:SI 2 "nonmemory_operand" "ri"))]
""
"wr_insert %1
\;
insert %0,%0,%2")
;; Constant propagation can optimize the previous pattern into this pattern.
;
[
Not any more. It could when the position-operand contains a MULT.
]
;(define_insn ""
;
[
(set (zero_extract:QI (match_operand:SI 0 "register_operand" "+r")
; (const_int 8)
; (match_operand:SI 1 "immediate_operand" "I"))
; (match_operand:QI 2 "register_operand" "r"))]
; "GET_CODE (operands
[
1
]
) == CONST_INT
; && INTVAL (operands
[
1
]
) % 8 == 0
; && (unsigned) INTVAL (operands
[
1
]
) < 32"
; "
*
;{
; operands
[
1
]
= gen_rtx (CONST_INT, VOIDmode, INTVAL (operands
[
1
]
) / 8);
; return
\"
wr_insert 0,0,%1
\;
insert %0,%0,%2
\"
;
;}")
;; The three define_expand patterns on this page
;; serve as subroutines of "movhi".
;; Generate code to fetch an aligned halfword from memory.
;; Operand 0 is the destination register (HImode).
;; Operand 1 is the memory address (SImode).
;; Operand 2 is a temporary (SImode).
;; Operand 3 is a temporary (SImode).
;; Operand 4 is a temporary (QImode).
;; Operand 5 is an internal temporary (HImode).
(define_expand "loadhi"
[
(set (match_operand:SI 2 "register_operand" "")
(mem:SI (match_operand:SI 1 "register_operand" "")))
;; Extract the low byte.
(set (subreg:SI (match_dup 5) 0)
(zero_extract:SI (match_dup 2) (const_int 8) (match_dup 1)))
;; Form address of high byte.
(set (match_operand:SI 3 "register_operand" "")
(plus:SI (match_dup 1) (const_int 1)))
;; Extract the high byte.
(set (subreg:SI (match_operand:QI 4 "register_operand" "") 0)
(zero_extract:SI (match_dup 2) (const_int 8) (match_dup 3)))
;; Put the high byte in with the low one.
(set (zero_extract:SI (match_dup 5) (const_int 8) (const_int 1))
(subreg:SI (match_dup 4) 0))
(set (match_operand:HI 0 "register_operand" "") (match_dup 5))]
""
"operands
[
5
]
= gen_reg_rtx (HImode);")
;; Generate code to store an aligned halfword into memory.
;; Operand 0 is the destination address (SImode).
;; Operand 1 is the source register (HImode, not constant).
;; Operand 2 is a temporary (SImode).
;; Operand 3 is a temporary (SImode).
;; Operand 4 is a temporary (QImode).
;; Operand 5 is an internal variable made from operand 1.
(define_expand "storehi"
[
(set (match_operand:SI 2 "register_operand" "")
(mem:SI (match_operand:SI 0 "register_operand" "")))
;; Insert the low byte.
(set (zero_extract:SI (match_dup 2) (const_int 8) (match_dup 0))
(match_dup 5))
;; Form address of high byte.
(set (match_operand:SI 3 "register_operand" "")
(plus:SI (match_dup 0) (const_int 1)))
;; Extract the high byte from the source.
(set (subreg:SI (match_operand:QI 4 "register_operand" "") 0)
(zero_extract:SI (match_operand:HI 1 "register_operand" "")
(const_int 8) (const_int 1)))
;; Store high byte into the memory word
(set (zero_extract:SI (match_dup 2) (const_int 8) (match_dup 3))
(subreg:SI (match_dup 4) 0))
;; Put memory word back into memory.
(set (mem:SI (match_dup 0))
(match_dup 2))]
""
"
{
if (GET_CODE (operands
[
1
]
) == SUBREG)
operands
[
5
]
= gen_rtx (SUBREG, SImode, SUBREG_REG (operands
[
1
]
),
SUBREG_WORD (operands
[
1
]
));
else
operands
[
5
]
= gen_rtx (SUBREG, SImode, operands
[
1
]
, 0);
}")
;; Like storehi but operands
[
1
]
is a CONST_INT.
(define_expand "storeinthi"
[
(set (match_operand:SI 2 "register_operand" "")
(mem:SI (match_operand:SI 0 "register_operand" "")))
;; Insert the low byte.
(set (zero_extract:SI (match_dup 2) (const_int 8) (match_dup 0))
(match_dup 5))
;; Form address of high byte.
(set (match_operand:SI 3 "register_operand" "")
(plus:SI (match_dup 0) (const_int 1)))
;; Store high byte into the memory word
(set (zero_extract:SI (match_dup 2) (const_int 8) (match_dup 3))
(match_dup 6))
;; Put memory word back into memory.
(set (mem:SI (match_dup 0))
(match_dup 2))]
""
" operands
[
5
]
= gen_rtx (CONST_INT, VOIDmode, INTVAL (operands
[
1
]
) & 255);
operands
[
6
]
= gen_rtx (CONST_INT, VOIDmode,
(INTVAL (operands
[
1
]
) >> 8) & 255);
")
;; Main entry for generating insns to move halfwords.
(define_expand "movhi"
[
(set (match_operand:HI 0 "general_operand" "")
(match_operand:HI 1 "general_operand" ""))]
""
"
{
if (GET_CODE (operands
[
0
]
) == MEM && GET_CODE (operands
[
1
]
) == MEM)
operands
[
1
]
= copy_to_reg (operands
[
1
]
);
if (GET_CODE (operands
[
1
]
) == MEM)
{
rtx insn =
emit_insn (gen_loadhi (operands
[
0
]
,
force_reg (SImode, XEXP (operands
[
1
]
, 0)),
gen_reg_rtx (SImode), gen_reg_rtx (SImode),
gen_reg_rtx (QImode)));
/
* Tell cse what value the loadhi produces, so it detect duplicates. *
/
REG_NOTES (insn) = gen_rtx (EXPR_LIST, REG_EQUAL, operands
[
1
]
,
REG_NOTES (insn));
}
else if (GET_CODE (operands
[
0
]
) == MEM)
{
if (GET_CODE (operands
[
1
]
) == CONST_INT)
emit_insn (gen_storeinthi (force_reg (SImode, XEXP (operands
[
0
]
, 0)),
operands
[
1
]
,
gen_reg_rtx (SImode), gen_reg_rtx (SImode),
gen_reg_rtx (QImode)));
else
{
if (CONSTANT_P (operands
[
1
]
))
operands
[
1
]
= force_reg (HImode, operands
[
1
]
);
emit_insn (gen_storehi (force_reg (SImode, XEXP (operands
[
0
]
, 0)),
operands
[
1
]
,
gen_reg_rtx (SImode), gen_reg_rtx (SImode),
gen_reg_rtx (QImode)));
}
}
else
emit_insn (gen_rtx (SET, VOIDmode, operands
[
0
]
, operands
[
1
]
));
DONE;
}")
;; Recognize insns generated for moving halfwords.
;; (Note that the extract and insert patterns for single-byte moves
;; are also involved in recognizing some of the insns used for this purpose.)
(define_insn ""
[
(set (match_operand:HI 0 "general_operand" "=r,m")
(match_operand:HI 1 "general_operand" "rmi,r"))]
""
"
*
{
if (GET_CODE (operands
[
0
]
) == MEM)
return
\"
st_32 %1,%0
\"
;
if (GET_CODE (operands
[
1
]
) == MEM)
return
\"
ld_32 %0,%1
\;
nop
\"
;
if (GET_CODE (operands
[
1
]
) == REG)
return
\"
add_nt %0,%1,$0
\"
;
return
\"
add_nt %0,r0,%1
\"
;
}")
(define_insn ""
[
(set (match_operand:SI 0 "register_operand" "=r")
(zero_extract:SI (match_operand:HI 1 "register_operand" "r")
(const_int 8)
(match_operand:SI 2 "nonmemory_operand" "rI")))]
""
"extract %0,%1,%2")
(define_insn ""
[
(set (zero_extract:SI (match_operand:HI 0 "register_operand" "+r")
(const_int 8)
(match_operand:SI 1 "nonmemory_operand" "rI"))
(match_operand:SI 2 "nonmemory_operand" "ri"))]
""
"wr_insert %1
\;
insert %0,%0,%2")
;; Constant propagation can optimize the previous pattern into this pattern.
;(define_insn ""
;
[
(set (zero_extract:QI (match_operand:HI 0 "register_operand" "+r")
; (const_int 8)
; (match_operand:SI 1 "immediate_operand" "I"))
; (match_operand:QI 2 "register_operand" "r"))]
; "GET_CODE (operands
[
1
]
) == CONST_INT
; && INTVAL (operands
[
1
]
) % 8 == 0
; && (unsigned) INTVAL (operands
[
1
]
) < 32"
; "
*
;{
; operands
[
1
]
= gen_rtx (CONST_INT, VOIDmode, INTVAL (operands
[
1
]
) / 8);
; return
\"
wr_insert 0,0,%1
\;
insert %0,%0,%2
\"
;
;}")
;; This pattern forces (set (reg:DF ...) (const_double ...))
;; to be reloaded by putting the constant into memory.
;; It must come before the more general movdf pattern.
(define_insn ""
[
(set (match_operand:DF 0 "general_operand" "=&r,f,&o")
(match_operand:DF 1 "" "mG,m,G"))]
"GET_CODE (operands
[
1
]
) == CONST_DOUBLE"
"
*
{
if (FP_REG_P (operands
[
0
]
))
return output_fp_move_double (operands);
if (operands
[
1
]
== CONST0_RTX (DFmode) && GET_CODE (operands
[
0
]
) == REG)
{
operands
[
1
]
= gen_rtx (REG, SImode, REGNO (operands
[
0
]
) + 1);
return
\"
add_nt %0,r0,$0
\;
add_nt %1,r0,$0
\"
;
}
if (operands
[
1
]
== CONST0_RTX (DFmode) && GET_CODE (operands
[
0
]
) == MEM)
{
operands
[
1
]
= adj_offsettable_operand (operands
[
0
]
, 4);
return
\"
st_32 r0,%0
\;
st_32 r0,%1
\"
;
}
return output_move_double (operands);
}
")
(define_insn "movdf"
[
(set (match_operand:DF 0 "general_operand" "=r,&r,m,?f,?rm")
(match_operand:DF 1 "general_operand" "r,m,r,rfm,f"))]
""
"
*
{
if (FP_REG_P (operands
[
0
]
) || FP_REG_P (operands
[
1
]
))
return output_fp_move_double (operands);
return output_move_double (operands);
}
")
(define_insn "movdi"
[
(set (match_operand:DI 0 "general_operand" "=r,&r,m,?f,?rm")
(match_operand:DI 1 "general_operand" "r,m,r,rfm,f"))]
""
"
*
{
if (FP_REG_P (operands
[
0
]
) || FP_REG_P (operands
[
1
]
))
return output_fp_move_double (operands);
return output_move_double (operands);
}
")
(define_insn "movsf"
[
(set (match_operand:SF 0 "general_operand" "=rf,m")
(match_operand:SF 1 "general_operand" "rfm,rf"))]
""
"
*
{
if (FP_REG_P (operands
[
0
]
))
{
if (FP_REG_P (operands
[
1
]
))
return
\"
fmov %0,%1
\"
;
if (GET_CODE (operands
[
1
]
) == REG)
{
rtx xoperands
[
2
]
;
int offset = - get_frame_size () - 8;
xoperands
[
1
]
= operands
[
1
]
;
xoperands
[
0
]
= gen_rtx (CONST_INT, VOIDmode, offset);
output_asm_insn (
\"
st_32 %1,r25,%0
\"
, xoperands);
xoperands
[
1
]
= operands
[
0
]
;
output_asm_insn (
\"
ld_sgl %1,r25,%0
\;
nop
\"
, xoperands);
return
\"\"
;
}
return
\"
ld_sgl %0,%1
\;
nop
\"
;
}
if (FP_REG_P (operands
[
1
]
))
{
if (GET_CODE (operands
[
0
]
) == REG)
{
rtx xoperands
[
2
]
;
int offset = - get_frame_size () - 8;
xoperands
[
0
]
= gen_rtx (CONST_INT, VOIDmode, offset);
xoperands
[
1
]
= operands
[
1
]
;
output_asm_insn (
\"
st_sgl %1,r25,%0
\"
, xoperands);
xoperands
[
1
]
= operands
[
0
]
;
output_asm_insn (
\"
ld_32 %1,r25,%0
\;
nop
\"
, xoperands);
return
\"\"
;
}
return
\"
st_sgl %1,%0
\"
;
}
if (GET_CODE (operands
[
0
]
) == MEM)
return
\"
st_32 %r1,%0
\"
;
if (GET_CODE (operands
[
1
]
) == MEM)
return
\"
ld_32 %0,%1
\;
nop
\"
;
if (GET_CODE (operands
[
1
]
) == REG)
return
\"
add_nt %0,%1,$0
\"
;
return
\"
add_nt %0,r0,%1
\"
;
}")
;;- truncation instructions
(define_insn "truncsiqi2"
[
(set (match_operand:QI 0 "register_operand" "=r")
(truncate:QI
(match_operand:SI 1 "register_operand" "r")))]
""
"add_nt %0,%1,$0")
(define_insn "trunchiqi2"
[
(set (match_operand:QI 0 "register_operand" "=r")
(truncate:QI
(match_operand:HI 1 "register_operand" "r")))]
""
"add_nt %0,%1,$0")
(define_insn "truncsihi2"
[
(set (match_operand:HI 0 "register_operand" "=r")
(truncate:HI
(match_operand:SI 1 "register_operand" "r")))]
""
"add_nt %0,%1,$0")
;;- zero extension instructions
;; Note that the one starting from HImode comes before those for QImode
;; so that a constant operand will match HImode, not QImode.
(define_expand "zero_extendhisi2"
[
(set (match_operand:SI 0 "register_operand" "")
(and:SI (match_operand:HI 1 "register_operand" "") ;Changed to SI below
;; This constant is invalid, but reloading will handle it.
;; It's useless to generate here the insns to construct it
;; because constant propagation would simplify them anyway.
(match_dup 2)))]
""
"
{
if (GET_CODE (operands
[
1
]
) == SUBREG)
operands
[
1
]
= gen_rtx (SUBREG, SImode, SUBREG_REG (operands
[
1
]
),
SUBREG_WORD (operands
[
1
]
));
else
operands
[
1
]
= gen_rtx (SUBREG, SImode, operands
[
1
]
, 0);
operands
[
2
]
= force_reg (SImode, gen_rtx (CONST_INT, VOIDmode, 65535));
}")
(define_insn "zero_extendqihi2"
[
(set (match_operand:HI 0 "register_operand" "=r")
(zero_extend:HI
(match_operand:QI 1 "register_operand" "r")))]
""
"extract %0,%1,$0")
(define_insn "zero_extendqisi2"
[
(set (match_operand:SI 0 "register_operand" "=r")
(zero_extend:SI
(match_operand:QI 1 "register_operand" "r")))]
""
"extract %0,%1,$0")
;;- sign extension instructions
;; Note that the one starting from HImode comes before those for QImode
;; so that a constant operand will match HImode, not QImode.
(define_expand "extendhisi2"
[
(set (match_dup 2)
(and:SI (match_operand:HI 1 "register_operand" "") ;Changed to SI below
(match_dup 4)))
(set (match_dup 3) (plus:SI (match_dup 2) (match_dup 5)))
(set (match_operand:SI 0 "register_operand" "")
(xor:SI (match_dup 3) (match_dup 5)))]
""
"
{
if (GET_CODE (operands
[
1
]
) == SUBREG)
operands
[
1
]
= gen_rtx (SUBREG, SImode, SUBREG_REG (operands
[
1
]
),
SUBREG_WORD (operands
[
1
]
));
else
operands
[
1
]
= gen_rtx (SUBREG, SImode, operands
[
1
]
, 0);
operands
[
2
]
= gen_reg_rtx (SImode);
operands
[
3
]
= gen_reg_rtx (SImode);
operands
[
4
]
= force_reg (SImode, gen_rtx (CONST_INT, VOIDmode, 65535));
operands
[
5
]
= force_reg (SImode, gen_rtx (CONST_INT, VOIDmode, -32768));
}")
(define_expand "extendqihi2"
[
(set (match_dup 2)
(and:HI (match_operand:QI 1 "register_operand" "") ;Changed to SI below
(const_int 255)))
(set (match_dup 3)
(plus:SI (match_dup 2) (const_int -128)))
(set (match_operand:HI 0 "register_operand" "")
(xor:SI (match_dup 3) (const_int -128)))]
""
"
{
if (GET_CODE (operands
[
1
]
) == SUBREG)
operands
[
1
]
= gen_rtx (SUBREG, HImode, SUBREG_REG (operands
[
1
]
),
SUBREG_WORD (operands
[
1
]
));
else
operands
[
1
]
= gen_rtx (SUBREG, HImode, operands
[
1
]
, 0);
operands
[
2
]
= gen_reg_rtx (HImode);
operands
[
3
]
= gen_reg_rtx (HImode);
}")
(define_expand "extendqisi2"
[
(set (match_dup 2)
(and:SI (match_operand:QI 1 "register_operand" "") ;Changed to SI below
(const_int 255)))
(set (match_dup 3) (plus:SI (match_dup 2) (const_int -128)))
(set (match_operand:SI 0 "register_operand" "")
(xor:SI (match_dup 3) (const_int -128)))]
""
"
{
if (GET_CODE (operands
[
1
]
) == SUBREG)
operands
[
1
]
= gen_rtx (SUBREG, SImode, SUBREG_REG (operands
[
1
]
),
SUBREG_WORD (operands
[
1
]
));
else
operands
[
1
]
= gen_rtx (SUBREG, SImode, operands
[
1
]
, 0);
operands
[
2
]
= gen_reg_rtx (SImode);
operands
[
3
]
= gen_reg_rtx (SImode);
}")
;;- arithmetic instructions
(define_insn "addsi3"
[
(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (match_operand:SI 1 "nonmemory_operand" "%r")
(match_operand:SI 2 "nonmemory_operand" "rI")))]
""
"add %0,%1,%2")
(define_insn ""
[
(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (match_operand:SI 1 "nonmemory_operand" "%r")
(match_operand:SI 2 "big_immediate_operand" "g")))]
"GET_CODE (operands
[
2
]
) == CONST_INT
&& (unsigned) (INTVAL (operands
[
2
]
) + 0x8000000) < 0x10000000"
"
*
{
return
output_add_large_offset (operands
[
0
]
, operands
[
1
]
, INTVAL (operands
[
2
]
));
}")
(define_insn "subsi3"
[
(set (match_operand:SI 0 "register_operand" "=r")
(minus:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "nonmemory_operand" "rI")))]
""
"sub %0,%1,%2")
(define_insn "andsi3"
[
(set (match_operand:SI 0 "register_operand" "=r")
(and:SI (match_operand:SI 1 "nonmemory_operand" "%r")
(match_operand:SI 2 "nonmemory_operand" "rI")))]
""
"and %0,%1,%2")
(define_insn "iorsi3"
[
(set (match_operand:SI 0 "register_operand" "=r")
(ior:SI (match_operand:SI 1 "nonmemory_operand" "%r")
(match_operand:SI 2 "nonmemory_operand" "rI")))]
""
"or %0,%1,%2")
(define_insn "xorsi3"
[
(set (match_operand:SI 0 "register_operand" "=r")
(xor:SI (match_operand:SI 1 "nonmemory_operand" "%r")
(match_operand:SI 2 "nonmemory_operand" "rI")))]
""
"xor %0,%1,%2")
(define_insn "negsi2"
[
(set (match_operand:SI 0 "register_operand" "=r")
(neg:SI (match_operand:SI 1 "nonmemory_operand" "rI")))]
""
"sub %0,r0,%1")
(define_insn "one_cmplsi2"
[
(set (match_operand:SI 0 "register_operand" "=r")
(not:SI (match_operand:SI 1 "register_operand" "r")))]
""
"xor %0,%1,$-1")
;; Floating point arithmetic instructions.
(define_insn "adddf3"
[
(set (match_operand:DF 0 "register_operand" "=f")
(plus:DF (match_operand:DF 1 "register_operand" "f")
(match_operand:DF 2 "register_operand" "f")))]
"TARGET_FPU"
"fadd %0,%1,%2")
(define_insn "addsf3"
[
(set (match_operand:SF 0 "register_operand" "=f")
(plus:SF (match_operand:SF 1 "register_operand" "f")
(match_operand:SF 2 "register_operand" "f")))]
"TARGET_FPU"
"fadd %0,%1,%2")
(define_insn "subdf3"
[
(set (match_operand:DF 0 "register_operand" "=f")
(minus:DF (match_operand:DF 1 "register_operand" "f")
(match_operand:DF 2 "register_operand" "f")))]
"TARGET_FPU"
"fsub %0,%1,%2")
(define_insn "subsf3"
[
(set (match_operand:SF 0 "register_operand" "=f")
(minus:SF (match_operand:SF 1 "register_operand" "f")
(match_operand:SF 2 "register_operand" "f")))]
"TARGET_FPU"
"fsub %0,%1,%2")
(define_insn "muldf3"
[
(set (match_operand:DF 0 "register_operand" "=f")
(mult:DF (match_operand:DF 1 "register_operand" "f")
(match_operand:DF 2 "register_operand" "f")))]
"TARGET_FPU"
"fmul %0,%1,%2")
(define_insn "mulsf3"
[
(set (match_operand:SF 0 "register_operand" "=f")
(mult:SF (match_operand:SF 1 "register_operand" "f")
(match_operand:SF 2 "register_operand" "f")))]
"TARGET_FPU"
"fmul %0,%1,%2")
(define_insn "divdf3"
[
(set (match_operand:DF 0 "register_operand" "=f")
(div:DF (match_operand:DF 1 "register_operand" "f")
(match_operand:DF 2 "register_operand" "f")))]
"TARGET_FPU"
"fdiv %0,%1,%2")
(define_insn "divsf3"
[
(set (match_operand:SF 0 "register_operand" "=f")
(div:SF (match_operand:SF 1 "register_operand" "f")
(match_operand:SF 2 "register_operand" "f")))]
"TARGET_FPU"
"fdiv %0,%1,%2")
(define_insn "negdf2"
[
(set (match_operand:DF 0 "register_operand" "=f")
(neg:DF (match_operand:DF 1 "nonmemory_operand" "f")))]
"TARGET_FPU"
"fneg %0,%1")
(define_insn "negsf2"
[
(set (match_operand:SF 0 "register_operand" "=f")
(neg:SF (match_operand:SF 1 "nonmemory_operand" "f")))]
"TARGET_FPU"
"fneg %0,%1")
(define_insn "absdf2"
[
(set (match_operand:DF 0 "register_operand" "=f")
(abs:DF (match_operand:DF 1 "nonmemory_operand" "f")))]
"TARGET_FPU"
"fabs %0,%1")
(define_insn "abssf2"
[
(set (match_operand:SF 0 "register_operand" "=f")
(abs:SF (match_operand:SF 1 "nonmemory_operand" "f")))]
"TARGET_FPU"
"fabs %0,%1")
;; Shift instructions
(define_insn ""
[
(set (match_operand:SI 0 "register_operand" "=r")
(ashift:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "immediate_operand" "I")))]
"GET_CODE (operands
[
2
]
) == CONST_INT"
"
*
{
unsigned int amount = INTVAL (operands
[
2
]
);
switch (amount)
{
case 0:
return
\"
add_nt %0,%1,$0
\"
;
case 1:
return
\"
sll %0,%1,$1
\"
;
case 2:
return
\"
sll %0,%1,$2
\"
;
default:
output_asm_insn (
\"
sll %0,%1,$3
\"
, operands);
for (amount -= 3; amount >= 3; amount -= 3)
output_asm_insn (\"sll %0,%0,$3\", operands);
if (amount > 0)
output_asm_insn (amount == 1 ? \"sll %0,%0,$1\" : \"sll %0,%0,$2\",
operands);
return \"\";
}
}")
(define_insn ""
[
(set (match_operand:SI 0 "register_operand" "=r")
(ashiftrt:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "immediate_operand" "I")))]
"GET_CODE (operands
[
2
]
) == CONST_INT"
"
*
{
unsigned int amount = INTVAL (operands
[
2
]
);
if (amount == 0)
return
\"
add_nt %0,%1,$0
\"
;
else
output_asm_insn (
\"
sra %0,%1,$1
\"
, operands);
for (amount -= 1; amount > 0; amount -= 1)
output_asm_insn (
\"
sra %0,%0,$1
\"
, operands);
return
\"\"
;
}")
(define_insn ""
[
(set (match_operand:SI 0 "register_operand" "=r")
(lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "immediate_operand" "I")))]
"GET_CODE (operands
[
2
]
) == CONST_INT"
"
*
{
unsigned int amount = INTVAL (operands
[
2
]
);
if (amount == 0)
return
\"
add_nt %0,%1,$0
\"
;
else
output_asm_insn (
\"
srl %0,%1,$1
\"
, operands);
for (amount -= 1; amount > 0; amount -= 1)
output_asm_insn (
\"
srl %0,%0,$1
\"
, operands);
return
\"\"
;
}")
(define_expand "ashlsi3"
[
(set (match_operand:SI 0 "register_operand" "")
(ashift:SI (match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "nonmemory_operand" "")))]
""
"
{
if (GET_CODE (operands
[
2
]
) != CONST_INT
|| (! TARGET_EXPAND_SHIFTS && (unsigned) INTVAL (operands
[
2
]
) > 3))
FAIL;
}")
(define_expand "lshlsi3"
[
(set (match_operand:SI 0 "register_operand" "")
(ashift:SI (match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "nonmemory_operand" "")))]
""
"
{
if (GET_CODE (operands
[
2
]
) != CONST_INT
|| (! TARGET_EXPAND_SHIFTS && (unsigned) INTVAL (operands
[
2
]
) > 3))
FAIL;
}")
(define_expand "ashrsi3"
[
(set (match_operand:SI 0 "register_operand" "")
(ashiftrt:SI (match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "nonmemory_operand" "")))]
""
"
{
if (GET_CODE (operands
[
2
]
) != CONST_INT
|| (! TARGET_EXPAND_SHIFTS && (unsigned) INTVAL (operands
[
2
]
) > 1))
FAIL;
}")
(define_expand "lshrsi3"
[
(set (match_operand:SI 0 "register_operand" "")
(lshiftrt:SI (match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "nonmemory_operand" "")))]
""
"
{
if (GET_CODE (operands
[
2
]
) != CONST_INT
|| (! TARGET_EXPAND_SHIFTS && (unsigned) INTVAL (operands
[
2
]
) > 1))
FAIL;
}")
;; Unconditional and other jump instructions
(define_insn "jump"
[
(set (pc)
(label_ref (match_operand 0 "" "")))]
""
"jump %l0
\;
nop")
(define_insn "tablejump"
[
(set (pc) (match_operand:SI 0 "register_operand" "r"))
(use (label_ref (match_operand 1 "" "")))]
""
"jump_reg r0,%0
\;
nop")
;;- jump to subroutine
(define_insn "call"
[
(call (match_operand:SI 0 "memory_operand" "m")
(match_operand:SI 1 "general_operand" "g"))]
;;- Don't use operand 1 for most machines.
""
"add_nt r2,%0
\;
call .+8
\;
jump_reg r0,r2
\;
nop")
(define_insn "call_value"
[
(set (match_operand 0 "" "=g")
(call (match_operand:SI 1 "memory_operand" "m")
(match_operand:SI 2 "general_operand" "g")))]
;;- Don't use operand 1 for most machines.
""
"add_nt r2,%1
\;
call .+8
\;
jump_reg r0,r2
\;
nop")
;; A memory ref with constant address is not normally valid.
;; But it is valid in a call insns. This pattern allows the
;; loading of the address to combine with the call.
(define_insn ""
[
(call (mem:SI (match_operand:SI 0 "" "i"))
(match_operand:SI 1 "general_operand" "g"))]
;;- Don't use operand 1 for most machines.
"GET_CODE (operands
[
0
]
) == SYMBOL_REF"
"call %0
\;
nop")
(define_insn ""
[
(set (match_operand 0 "" "=g")
(call (mem:SI (match_operand:SI 1 "" "i"))
(match_operand:SI 2 "general_operand" "g")))]
;;- Don't use operand 1 for most machines.
"GET_CODE (operands
[
1
]
) == SYMBOL_REF"
"call %1
\;
nop")
(define_insn "nop"
[
(const_int 0)
]
""
"nop")
;;- Local variables:
;;- mode:emacs-lisp
;;- comment-start: ";;- "
;;- eval: (set-syntax-table (copy-sequence (syntax-table)))
;;- eval: (modify-syntax-entry ?
[
"(
]
")
;;- eval: (modify-syntax-entry ?] ")
[
")
;;- eval: (modify-syntax-entry ?{ "(}")
;;- eval: (modify-syntax-entry ?} "){")
;;- End:
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