public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* RTL to Simple Three instruction code
@ 2002-12-10 23:20 Aditya Kanade
  2002-12-10 23:29 ` Peter Barada
  2002-12-11  7:17 ` Diego Novillo
  0 siblings, 2 replies; 7+ messages in thread
From: Aditya Kanade @ 2002-12-10 23:20 UTC (permalink / raw)
  To: gcc

Hi,

I'm working on a project which involves performing some optimizations
and annotating three-address code. We've been looking for some suitable
framework which can give us IR (in three-instruction format). We studied
many compiler infrastructures like SUIF, trimaran, zephyr and so on.

We feel that we can use gcc keeping in mind long-term usability and
extensibility. So is there any way of generating simple three-instruction
code from RTL (or tree representation) of gcc? Or is there a way of
reading and writing the string representation of RTL so that we can decide
on our own IR? Any help and suggestions for a getting three-instruction
code or writting programs for doing so will be of very much help.

---
Aditya Kanade.
M.Tech. Student, CSE, IIT Bombay.

http://www.cse.iitb.ac.in/~aditya

I've learned to keep my mind as open as I can.
I'm trying to look in as many directions as I can,
to find as many doors as I can, and I'm not going to
stop until I open them all.


^ permalink raw reply	[flat|nested] 7+ messages in thread
* Re: RTL to Simple Three instruction code
@ 2002-12-10 23:36 Chris Lattner
  2002-12-10 23:30 ` Chris Lattner
  0 siblings, 1 reply; 7+ messages in thread
From: Chris Lattner @ 2002-12-10 23:36 UTC (permalink / raw)
  To: Peter Barada; +Cc: aditya, gcc

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1043 bytes --]


>>I'm working on a project which involves performing some optimizations
>>and annotating three-address code. We've been looking for some suitable
>>framework which can give us IR (in three-instruction format). We studied
>>many compiler infrastructures like SUIF, trimaran, zephyr and so on.

> I think it would be pretty easy to develop a GCC port to a three
> address architecture(TAA) paper machine.  In fact its probabaly easier
> to do that than any of the *real* chips that GCC has been ported to
> since there are little to *none* of the restrictions that real chips
> have(offset limitations, instruction/register scheduling, addressing
> restrictions, etc).

Here's the machine description file I wrote for the GCC frontend used by
the LLVM compiler infrastructure (http://llvm.cs.uiuc.edu/).  It is a very
abstract description which is used to export an IR from GCC.  It was
derived from the sparc.md file, but stripped down and simplified
drastically...

-Chris

-- 
http://llvm.cs.uiuc.edu/
http://www.nondot.org/~sabre/Projects/

[-- Attachment #2: Type: TEXT/PLAIN, Size: 49848 bytes --]

;;- Machine description for LLVM "chip" for GNU C compiler -*- lisp -*-
;;  Copyright (C) 2001 Free Software Foundation, Inc.
;;  Contributed by Chris Lattner (sabre@nondot.org)

;; 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, 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.

;;- See file "rtl.def" for documentation on define_insn, match_*, et. al.

\f
;; Compare instructions.
;; This controls RTL generation and register allocation.

;; Now the compare DEFINE_INSNs.

(define_insn "cmpqi"
  [(set (reg:CC 100)
	(compare:CC (match_operand:QI 0 "nonmemory_nonsubreg_operand" "")
		    (match_operand:QI 1 "nonmemory_nonsubreg_operand" "")))]
  ""
  "cmpqi %0, %1")

(define_insn "cmphi"
  [(set (reg:CC 100)
	(compare:CC (match_operand:HI 0 "nonmemory_nonsubreg_operand" "")
		    (match_operand:HI 1 "nonmemory_nonsubreg_operand" "")))]
  ""
  "cmphi %0, %1")

(define_insn "cmpsi"
  [(set (reg:CC 100)
	(compare:CC (match_operand:SI 0 "nonmemory_nonsubreg_operand" "")
		    (match_operand:SI 1 "nonmemory_nonsubreg_operand" "")))]
  ""
  "cmpsi %0, %1")

(define_insn "cmpdi"
  [(set (reg:CC 100)
	(compare:CC (match_operand:DI 0 "nonmemory_nonsubreg_operand" "")
		    (match_operand:DI 1 "nonmemory_nonsubreg_operand" "")))]
  ""
  "cmpdi %0, %1")

(define_insn "cmppdi"
  [(set (reg:CC 100)
	(compare:CC (match_operand:PDI 0 "nonmemory_nonsubreg_operand" "")
		    (match_operand:PDI 1 "nonmemory_nonsubreg_operand" "")))]
  ""
  "cmppdi %0, %1")

(define_insn "cmpsf"
  [(set (reg:CC 100)
	(compare:CC (match_operand:SF 0 "nonmemory_nonsubreg_operand" "f")
		    (match_operand:SF 1 "nonmemory_nonsubreg_operand" "f")))]
  ""
  "cmpsf %0, %1")

(define_insn "cmpdf"
  [(set (reg:CC 100)
	(compare:CC (match_operand:DF 0 "nonmemory_nonsubreg_operand" "e")
		    (match_operand:DF 1 "nonmemory_nonsubreg_operand" "e")))]
  ""
  "cmpdf %0, %1")

\f

;; Define setcc instructions...

(define_insn "seq"
  [(set (match_operand:QI 0 "nonmemory_nonsubreg_operand" "=r")
        (eq:QI (reg:CC 100) (const_int 0)))]
  ""
  "")
(define_insn "sne"
  [(set (match_operand:QI 0 "nonmemory_nonsubreg_operand" "=r")
        (ne:QI (reg:CC 100) (const_int 0)))]
  ""
  "")
(define_insn "sgt"
  [(set (match_operand:QI 0 "nonmemory_nonsubreg_operand" "=r")
        (gt:QI (reg:CC 100) (const_int 0)))]
  ""
  "")
(define_insn "sgtu"
  [(set (match_operand:QI 0 "nonmemory_nonsubreg_operand" "=r")
        (gtu:QI (reg:CC 100) (const_int 0)))]
  ""
  "")
(define_insn "slt"
  [(set (match_operand:QI 0 "nonmemory_nonsubreg_operand" "=r")
        (lt:QI (reg:CC 100) (const_int 0)))]
  ""
  "")
(define_insn "sltu"
  [(set (match_operand:QI 0 "nonmemory_nonsubreg_operand" "=r")
        (ltu:QI (reg:CC 100) (const_int 0)))]
  ""
  "")
(define_insn "sge"
  [(set (match_operand:QI 0 "nonmemory_nonsubreg_operand" "=r")
        (ge:QI (reg:CC 100) (const_int 0)))]
  ""
  "")
(define_insn "sgeu"
  [(set (match_operand:QI 0 "nonmemory_nonsubreg_operand" "=r")
        (geu:QI (reg:CC 100) (const_int 0)))]
  ""
  "")
(define_insn "sle"
  [(set (match_operand:QI 0 "nonmemory_nonsubreg_operand" "=r")
        (le:QI (reg:CC 100) (const_int 0)))]
  ""
  "")
(define_insn "sleu"
  [(set (match_operand:QI 0 "nonmemory_nonsubreg_operand" "=r")
        (leu:QI (reg:CC 100) (const_int 0)))]
  ""
  "")
(define_insn "sunordered"
  [(set (match_operand:QI 0 "nonmemory_nonsubreg_operand" "=r")
        (unordered:QI (reg:CC 100) (const_int 0)))]
  ""
  "")
(define_insn "sordered"
  [(set (match_operand:QI 0 "nonmemory_nonsubreg_operand" "=r")
        (ordered:QI (reg:CC 100) (const_int 0)))]
  ""
  "")
(define_insn "sungt"
  [(set (match_operand:QI 0 "nonmemory_nonsubreg_operand" "=r")
        (ungt:QI (reg:CC 100) (const_int 0)))]
  ""
  "")
(define_insn "sunlt"
  [(set (match_operand:QI 0 "nonmemory_nonsubreg_operand" "=r")
        (unlt:QI (reg:CC 100) (const_int 0)))]
  ""
  "")
(define_insn "suneq"
  [(set (match_operand:QI 0 "nonmemory_nonsubreg_operand" "=r")
        (uneq:QI (reg:CC 100) (const_int 0)))]
  ""
  "")
(define_insn "sunge"
  [(set (match_operand:QI 0 "nonmemory_nonsubreg_operand" "=r")
        (unge:QI (reg:CC 100) (const_int 0)))]
  ""
  "")
(define_insn "sunle"
  [(set (match_operand:QI 0 "nonmemory_nonsubreg_operand" "=r")
        (unle:QI (reg:CC 100) (const_int 0)))]
  ""
  "")
(define_insn "sltgt"
  [(set (match_operand:QI 0 "nonmemory_nonsubreg_operand" "=r")
        (ltgt:QI (reg:CC 100) (const_int 0)))]
  ""
  "")





;; These control RTL generation for conditional jump insns

(define_expand "beq"
  [(set (pc)
	(if_then_else (eq (reg:CC 100) (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "")

(define_expand "bne"
  [(set (pc)
	(if_then_else (ne (reg:CC 100) (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "")

(define_expand "bgt"
  [(set (pc)
	(if_then_else (gt (reg:CC 100) (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "")

(define_expand "bgtu"
  [(set (pc)
	(if_then_else (gtu (reg:CC 100) (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "")

(define_expand "blt"
  [(set (pc)
	(if_then_else (lt (reg:CC 100) (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "")

(define_expand "bltu"
  [(set (pc)
	(if_then_else (ltu (reg:CC 100) (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "")

(define_expand "bge"
  [(set (pc)
	(if_then_else (ge (reg:CC 100) (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "")

(define_expand "bgeu"
  [(set (pc)
	(if_then_else (geu (reg:CC 100) (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "")

(define_expand "ble"
  [(set (pc)
	(if_then_else (le (reg:CC 100) (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "")

(define_expand "bleu"
  [(set (pc)
	(if_then_else (leu (reg:CC 100) (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "")

(define_expand "bunordered"
  [(set (pc)
	(if_then_else (unordered (reg:CC 100) (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "")

(define_expand "bordered"
  [(set (pc)
	(if_then_else (ordered (reg:CC 100) (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "")

(define_expand "bungt"
  [(set (pc)
	(if_then_else (ungt (reg:CC 100) (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "")

(define_expand "bunlt"
  [(set (pc)
	(if_then_else (unlt (reg:CC 100) (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "")

(define_expand "buneq"
  [(set (pc)
	(if_then_else (uneq (reg:CC 100) (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "")

(define_expand "bunge"
  [(set (pc)
	(if_then_else (unge (reg:CC 100) (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "")

(define_expand "bunle"
  [(set (pc)
	(if_then_else (unle (reg:CC 100) (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "")

(define_expand "bltgt"
  [(set (pc)
	(if_then_else (ltgt (reg:CC 100) (const_int 0))
		      (label_ref (match_operand 0 "" ""))
		      (pc)))]
  ""
  "")
\f
;; Now match both normal and inverted jump.

(define_insn "*normal_branch"
  [(set (pc)
        (if_then_else (match_operator 0 "v9_regcmp_op"
                                      [(reg 100) (const_int 0)])
                      (label_ref (match_operand 1 "" ""))
                      (pc)))]
  ""
  "br %0 to %1
")

(define_insn "*inverted_branch"
  [(set (pc)
        (if_then_else (match_operator 0 "v9_regcmp_op"
                                      [(reg 100) (const_int 0)])
                      (pc)
                      (label_ref (match_operand 1 "" ""))))]
  ""
  "br %0 to %1 (inverted!)
")

\f
;; Load program counter insns.

;;(define_insn "get_pc"
;;  [(clobber (reg:SI 15))
;;   (set (match_operand 0 "register_operand" "=r")
;;	(unspec [(match_operand 1 "" "") (match_operand 2 "" "")] 2))]
;;  "flag_pic && REGNO (operands[0]) == 23"
;;  "sethi\\t%%hi(%a1-4), %0\\n\\tcall\\t%a2\\n\\tadd\\t%0, %%lo(%a1+4), %0")

\f
;; Move instructions

(define_expand "movqi"
  [(set (match_operand:QI 0 "general_operand" "=rm")
	(match_operand:QI 1 "general_operand" ""))]
  ""
  "
{ /* One of the ops has to be in a register */
  if (!register_operand (operand0, QImode)
      && !register_operand (operand1, QImode))
    operands[1] = copy_to_mode_reg (QImode, operand1);
}")

(define_insn "*movqi"
  [(set (match_operand:QI 0 "nonimmediate_operand" "=rm")
	(match_operand:QI 1 "input_operand"        "rim"))]
  ""
  "movqi %1 -> %0")


(define_expand "movhi"
  [(set (match_operand:HI 0 "general_operand" "=rm")
	(match_operand:HI 1 "general_operand" ""))]
  ""
  "
{ /* One of the ops has to be in a register */
  if (!register_operand (operand0, HImode)
      && !register_operand (operand1, HImode))
    operands[1] = copy_to_mode_reg (HImode, operand1);
}")

;;[(set (match_operand:HI 0 "nonimmediate_operand" "=r,f,r,f,m,m")
;;	(match_operand:HI 1 "input_operand"        "ri,!f,m,!m,r,!f"))]
;;

(define_insn "*movhi"
  [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
	(match_operand:HI 1 "input_operand"        "rim"))]
  ""
  "movhi %1 -> %0")


(define_expand "movsi"
  [(set (match_operand:SI 0 "general_operand" "=rm")
	(match_operand:SI 1 "general_operand" ""))]
  ""
  "
{ /* One of the ops has to be in a register */
  if (!register_operand (operand0, SImode)
      && !register_operand (operand1, SImode))
    operands[1] = copy_to_mode_reg (SImode, operand1);
}")

(define_insn "*movsi"
  [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
	(match_operand:SI 1 "input_operand"        "rim"))]
  ""
  "movsi %1 -> %0")


(define_expand "movdi"
  [(set (match_operand:DI 0 "general_operand" "=rm")
	(match_operand:DI 1 "general_operand" ""))]
  ""
  "
{ /* One of the ops has to be in a register */
  if (!register_operand (operand0, DImode)
      && !register_operand (operand1, DImode))
    operands[1] = copy_to_mode_reg (DImode, operand1);
}")

(define_insn "*movdi"
  [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
	(match_operand:DI 1 "input_operand"        "rim"))]
  ""
  "movdi %1 -> %0")

(define_expand "movpdi"
  [(set (match_operand:PDI 0 "general_operand" "=rm")
	(match_operand:PDI 1 "general_operand" ""))]
  ""
  "
{ /* One of the ops has to be in a register */
  if (!register_operand (operand0, PDImode)
      && !register_operand (operand1, PDImode))
    operands[1] = copy_to_mode_reg (PDImode, operand1);
}")

(define_insn "*movpdi"
  [(set (match_operand:PDI 0 "nonimmediate_operand" "=rm")
	(match_operand:PDI 1 "input_operand"        "rim"))]
  ""
  "movpdi %1 -> %0")


;; mov_to_ret, mov_from_ret - These instructions are used to set the return
;; register for a function, or to read the value returned by a function.
;;
(define_insn "*mov_to_ret"
  [(set (reg 101) (match_operand 0 "input_operand" ""))]
  ""
  "movi %0 -> %%ret")

(define_insn "*mov_from_ret"
  [(set (match_operand 0 "register_operand" "")	(reg 101))]
  ""
  "movi %%ret -> %0")




\f
;; Floating point move insns

(define_expand "movsf"
  [(set (match_operand:SF 0 "general_operand" "")
	(match_operand:SF 1 "general_operand" ""))]
  ""
  "
{ /* One of the ops has to be in a register */
  if (!register_operand (operand0, SFmode)
      && !register_operand (operand1, SFmode))
    operands[1] = copy_to_mode_reg (SFmode, operand1);
}")

(define_insn "*movsf"
  [(set (match_operand:SF 0 "nonimmediate_operand" "")
	(match_operand:SF 1 "input_operand"         ""))]
  ""
  "movsf %1 -> %0")

(define_expand "movdf"
  [(set (match_operand:DF 0 "general_operand" "")
	(match_operand:DF 1 "general_operand" ""))]
  ""
  "
{ /* One of the ops has to be in a register */
  if (!register_operand (operand0, DFmode)
      && !register_operand (operand1, DFmode))
    operands[1] = copy_to_mode_reg (DFmode, operand1);
}")

(define_insn "*movdf"
  [(set (match_operand:DF 0 "nonimmediate_operand" "")
        (match_operand:DF 1 "input_operand"    ""))]
  ""
  "movdf %1 -> %0")

\f
;;- zero extension instructions

(define_insn "zero_extendqihi2"
  [(set (match_operand:HI 0 "register_operand" "=r")
	(zero_extend:HI (match_operand:QI 1 "nonmemory_nonsubreg_operand" "")))]
  ""
  "zero_extendqihi2 %1 -> %0")

(define_insn "zero_extendqisi2"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(zero_extend:SI (match_operand:QI 1 "nonmemory_nonsubreg_operand" "")))]
  ""
  "zero_extendqisi2 %1 -> %0")

(define_insn "zero_extendhisi2"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(zero_extend:SI (match_operand:HI 1 "nonmemory_nonsubreg_operand" "")))]
  ""
  "zero_extendhisi2 %1 -> %0")

(define_insn "zero_extendqidi2"
  [(set (match_operand:DI 0 "register_operand" "=r")
	(zero_extend:DI (match_operand:QI 1 "nonmemory_nonsubreg_operand" "")))]
  ""
  "zero_extendqidi2 %1 -> %0")

(define_insn "zero_extendhidi2"
  [(set (match_operand:DI 0 "register_operand" "=r")
	(zero_extend:DI (match_operand:HI 1 "nonmemory_nonsubreg_operand" "")))]
  ""
  "zero_extendhidi2 %1 -> %0")

(define_insn "zero_extendsidi2"
  [(set (match_operand:DI 0 "register_operand" "=r")
	(zero_extend:DI (match_operand:SI 1 "nonmemory_nonsubreg_operand" "")))]
  ""
  "zero_extendsidi2 %1 -> %0")


\f
;;- sign extension instructions

(define_insn "extendhisi2"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(sign_extend:SI (match_operand:HI 1 "nonmemory_nonsubreg_operand" "")))]
  ""
  "extendhisi2 %1 -> %0")

(define_insn "extendqihi2"
  [(set (match_operand:HI 0 "register_operand" "=r")
	(sign_extend:HI (match_operand:QI 1 "nonmemory_nonsubreg_operand" "")))]
  ""
  "extendqihi2 %1 -> %0")

(define_insn "extendqisi2"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(sign_extend:SI (match_operand:QI 1 "nonmemory_nonsubreg_operand" "")))]
  ""
  "extendqisi2 %1 -> %0")

(define_insn "extendqidi2"
  [(set (match_operand:DI 0 "register_operand" "=r")
	(sign_extend:DI (match_operand:QI 1 "nonmemory_nonsubreg_operand" "")))]
  ""
  "extendqidi2 %1 -> %0")

(define_insn "extendhidi2"
  [(set (match_operand:DI 0 "register_operand" "=r")
	(sign_extend:DI (match_operand:HI 1 "nonmemory_nonsubreg_operand" "")))]
  ""
  "extendhidi2 %1 -> %0")

(define_insn "extendsidi2"
  [(set (match_operand:DI 0 "register_operand" "=r")
	(sign_extend:DI (match_operand:SI 1 "nonmemory_nonsubreg_operand" "")))]
  ""
  "extendsidi2 %1 -> %0")

(define_insn "extendpdidi2"
  [(set (match_operand:DI 0 "register_operand" "=r")
        (zero_extend:DI (match_operand:PDI 1 "nonmemory_nonsubreg_operand" "")))]
  ""
  "extendpdidi2 %1 -> %0")



(define_insn "truncdipdi2"
  [(set (match_operand:PDI 0 "register_operand" "=r")
        (truncate:PDI (match_operand:DI 1 "nonmemory_nonsubreg_operand" "")))]
   ""
   "truncdipdi2 %1 -> %0")

(define_insn "truncdisi2"
  [(set (match_operand:SI 0 "register_operand" "=r")
        (truncate:SI (match_operand:DI 1 "nonmemory_nonsubreg_operand" "")))]
   ""
   "truncdisi2 %1 -> %0")

(define_insn "truncsihi2"
  [(set (match_operand:HI 0 "register_operand" "=r")
        (truncate:HI (match_operand:SI 1 "nonmemory_nonsubreg_operand" "")))]
   ""
   "truncsihi2 %1 -> %0")

(define_insn "trunchiqi2"
  [(set (match_operand:QI 0 "register_operand" "=r")
        (truncate:QI (match_operand:HI 1 "nonmemory_nonsubreg_operand" "")))]
   ""
   "trunchiqi2 %1 -> %0")

(define_insn "truncsiqi2"
  [(set (match_operand:QI 0 "register_operand" "=r")
        (truncate:QI (match_operand:SI 1 "nonmemory_nonsubreg_operand" "")))]
   ""
   "truncsiqi2 %1 -> %0")



\f

;; Conversions between float, double and long double.

(define_insn "extendsfdf2"
  [(set (match_operand:DF 0 "register_operand" "=e")
	(float_extend:DF
	 (match_operand:SF 1 "nonmemory_nonsubreg_operand" "f")))]
  ""
  "extendsfdf2 %1 -> %0")

(define_insn "truncdfsf2"
  [(set (match_operand:SF 0 "register_operand" "=f")
	(float_truncate:SF
	 (match_operand:DF 1 "nonmemory_nonsubreg_operand" "e")))]
  ""
  "truncdfsf2 %1 -> %0")



\f
;; Conversion between fixed point and floating point.

(define_insn "floatsisf2"
  [(set (match_operand:SF 0 "register_operand" "=f")
	(float:SF (match_operand:SI 1 "nonmemory_nonsubreg_operand" "f")))]
  ""
  "fitos\\t%1, %0")

(define_insn "floatsidf2"
  [(set (match_operand:DF 0 "register_operand" "=e")
	(float:DF (match_operand:SI 1 "nonmemory_nonsubreg_operand" "f")))]
  ""
  "fitod\\t%1, %0")

;; Now the same for 64 bit sources.

(define_insn "floatdisf2"
  [(set (match_operand:SF 0 "register_operand" "=f")
	(float:SF (match_operand:DI 1 "nonmemory_nonsubreg_operand" "e")))]
  ""
  "fxtos\\t%1, %0")

(define_insn "floatdidf2"
  [(set (match_operand:DF 0 "register_operand" "=e")
	(float:DF (match_operand:DI 1 "nonmemory_nonsubreg_operand" "e")))]
  ""
  "fxtod\\t%1, %0")



;; Convert a float to an actual integer.
;; Truncation is performed as part of the conversion.

(define_insn "fix_truncsfsi2"
  [(set (match_operand:SI 0 "register_operand" "=f")
	(fix:SI (match_operand:SF 1 "nonmemory_nonsubreg_operand" "f")))]
  ""
  "fix_truncsfsi2 %1, %0")

(define_insn "fix_truncdfsi2"
  [(set (match_operand:SI 0 "register_operand" "=f")
	(fix:SI (match_operand:DF 1 "nonmemory_nonsubreg_operand" "e")))]
  ""
  "fix_truncdfsi2 %1, %0")

(define_insn "fix_truncsfdi2"
  [(set (match_operand:DI 0 "register_operand" "=e")
	(fix:DI (match_operand:SF 1 "nonmemory_nonsubreg_operand" "f")))]
  ""
  "fix_truncsfdi2 %1, %0")

(define_insn "fix_truncdfdi2"
  [(set (match_operand:DI 0 "register_operand" "=e")
	(fix:DI (match_operand:DF 1 "nonmemory_nonsubreg_operand" "e")))]
  ""
  "fix_truncdfdi2 %1, %0")


(define_insn "fixuns_truncsfsi2"
  [(set (match_operand:SI 0 "register_operand" "=f")
	(unsigned_fix:SI (match_operand:SF 1 "nonmemory_nonsubreg_operand" "f")))]
  ""
  "fixuns_truncsfsi2 %1, %0")

(define_insn "fixuns_truncdfsi2"
  [(set (match_operand:SI 0 "register_operand" "=f")
	(unsigned_fix:SI (match_operand:DF 1 "nonmemory_nonsubreg_operand" "e")))]
  ""
  "fixuns_truncdfsi2 %1, %0")

(define_insn "fixuns_truncsfdi2"
  [(set (match_operand:DI 0 "register_operand" "=e")
	(unsigned_fix:DI (match_operand:SF 1 "nonmemory_nonsubreg_operand" "f")))]
  ""
  "fixuns_truncsfdi2 %1, %0")

(define_insn "fixuns_truncdfdi2"
  [(set (match_operand:DI 0 "register_operand" "=e")
	(unsigned_fix:DI (match_operand:DF 1 "nonmemory_nonsubreg_operand" "e")))]
  ""
  "fixuns_truncdfdi2 %1, %0")


\f
;;- arithmetic instructions

(define_insn "adddi3"
  [(set (match_operand:DI 0 "register_operand" "=r")
	(plus:DI (match_operand:DI 1 "nonmemory_nonsubreg_operand" "")
		 (match_operand:DI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "adddi3 %1, %2 -> %0")

(define_insn "addsi3"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(plus:SI (match_operand:SI 1 "nonmemory_nonsubreg_operand" "")
		 (match_operand:SI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "addsi3 %1, %2 -> %0")

(define_insn "addpdi3"
  [(set (match_operand:PDI 0 "register_operand" "=r")
	(plus:PDI (match_operand:PDI 1 "nonmemory_nonsubreg_operand" "")
		 (match_operand:PDI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "addpdi3 %1, %2 -> %0")

(define_insn "addhi3"
  [(set (match_operand:HI 0 "register_operand" "=r")
	(plus:HI (match_operand:HI 1 "nonmemory_nonsubreg_operand" "")
		 (match_operand:HI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "addhi3 %1, %2 -> %0")

(define_insn "addqi3"
  [(set (match_operand:QI 0 "register_operand" "=r")
	(plus:QI (match_operand:QI 1 "nonmemory_nonsubreg_operand" "")
		 (match_operand:QI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "addqi3 %1, %2 -> %0")

(define_insn "adddf3"
  [(set (match_operand:DF 0 "register_operand" "=e")
	(plus:DF (match_operand:DF 1 "nonmemory_nonsubreg_operand" "e")
		 (match_operand:DF 2 "nonmemory_nonsubreg_operand" "e")))]
  ""
  "adddf3 %1, %2 -> %0")

(define_insn "addsf3"
  [(set (match_operand:SF 0 "register_operand" "=f")
	(plus:SF (match_operand:SF 1 "nonmemory_nonsubreg_operand" "f")
		 (match_operand:SF 2 "nonmemory_nonsubreg_operand" "f")))]
  ""
  "addsf3 %1, %2 -> %0")


;; Subtraction instructions

(define_insn "subdi3"
  [(set (match_operand:DI 0 "register_operand" "=r")
	(minus:DI (match_operand:DI 1 "nonmemory_nonsubreg_operand" "")
		  (match_operand:DI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "subdi %1, %2, %0")

(define_insn "subsi3"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(minus:SI (match_operand:SI 1 "nonmemory_nonsubreg_operand" "")
		  (match_operand:SI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "subsi %1, %2, %0")

(define_insn "subhi3"
  [(set (match_operand:HI 0 "register_operand" "=r")
	(minus:HI (match_operand:HI 1 "nonmemory_nonsubreg_operand" "")
		  (match_operand:HI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "subhi %1, %2, %0")

(define_insn "subqi3"
  [(set (match_operand:QI 0 "register_operand" "=r")
	(minus:QI (match_operand:QI 1 "nonmemory_nonsubreg_operand" "")
		  (match_operand:QI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "subqi %1, %2, %0")


(define_expand "subpdi3"
  [(set (match_dup 3)
        (zero_extend:DI (match_operand:PDI 1 "nonmemory_nonsubreg_operand" "")))
   (set (match_dup 4)
        (zero_extend:DI (match_operand:PDI 2 "nonmemory_nonsubreg_operand" "")))
   (set  (match_dup 5)
         (minus:DI (match_dup 3) (match_dup 4)))
   (set (match_operand:PDI 0 "register_operand" "=r")
        (truncate:PDI (match_dup 5)))]
  ""
  "
{
  operands[3] = gen_reg_rtx(DImode);
  operands[4] = gen_reg_rtx(DImode);
  operands[5] = gen_reg_rtx(DImode);
}")


(define_insn "subdf3"
  [(set (match_operand:DF 0 "register_operand" "=e")
	(minus:DF (match_operand:DF 1 "nonmemory_nonsubreg_operand" "e")
		  (match_operand:DF 2 "nonmemory_nonsubreg_operand" "e")))]
  ""
  "subdf3 %1, %2 -> %0")

(define_insn "subsf3"
  [(set (match_operand:SF 0 "register_operand" "=f")
	(minus:SF (match_operand:SF 1 "nonmemory_nonsubreg_operand" "f")
		  (match_operand:SF 2 "nonmemory_nonsubreg_operand" "f")))]
  ""
  "subsf3 %1, %2 -> %0")

\f
;; Integer Multiply/Divide.

(define_insn "mulqi3"
  [(set (match_operand:QI 0 "register_operand" "=r")
	(mult:QI (match_operand:QI 1 "nonmemory_nonsubreg_operand" "")
		 (match_operand:QI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "mulqi3\\t%1, %2 -> %0")

(define_insn "mulhi3"
  [(set (match_operand:HI 0 "register_operand" "=r")
	(mult:HI (match_operand:HI 1 "nonmemory_nonsubreg_operand" "")
		 (match_operand:HI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "mulhi3 %1, %2 -> %0")

(define_insn "mulsi3"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(mult:SI (match_operand:SI 1 "nonmemory_nonsubreg_operand" "")
		 (match_operand:SI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "mulsi3 %1, %2 -> %0")

(define_insn "muldi3"
  [(set (match_operand:DI 0 "register_operand" "=r")
	(mult:DI (match_operand:DI 1 "nonmemory_nonsubreg_operand" "")
		 (match_operand:DI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "muldi3 %1, %2 -> %0")

(define_expand "mulpdi3"
  [(set (match_dup 3)
        (zero_extend:DI (match_operand:PDI 1 "nonmemory_nonsubreg_operand" "")))
   (set (match_dup 4)
        (zero_extend:DI (match_operand:PDI 2 "nonmemory_nonsubreg_operand" "")))
   (set  (match_dup 5)
         (mult:DI (match_dup 3) (match_dup 4)))
   (set (match_operand:PDI 0 "register_operand" "=r")
        (truncate:PDI (match_dup 5)))]
  ""
  "
{
  operands[3] = gen_reg_rtx(DImode);
  operands[4] = gen_reg_rtx(DImode);
  operands[5] = gen_reg_rtx(DImode);
}")



(define_insn "muldf3"
  [(set (match_operand:DF 0 "register_operand" "=e")
	(mult:DF (match_operand:DF 1 "nonmemory_nonsubreg_operand" "e")
		 (match_operand:DF 2 "nonmemory_nonsubreg_operand" "e")))]
  ""
  "muldf3 %1, %2 -> %0")

(define_insn "mulsf3"
  [(set (match_operand:SF 0 "register_operand" "=f")
	(mult:SF (match_operand:SF 1 "nonmemory_nonsubreg_operand" "f")
		 (match_operand:SF 2 "nonmemory_nonsubreg_operand" "f")))]
  ""
  "mulsf3 %1, %2 -> %0")

;; Division instructions

(define_insn "divqi3"
  [(set (match_operand:QI 0 "register_operand" "=r")
	(div:QI (match_operand:QI 1 "nonmemory_nonsubreg_operand" "")
		 (match_operand:QI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "divqi3 %1, %2 -> %0")

(define_insn "divhi3"
  [(set (match_operand:HI 0 "register_operand" "=r")
	(div:HI (match_operand:HI 1 "nonmemory_nonsubreg_operand" "")
		 (match_operand:HI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "divhi3 %1, %2 -> %0")

(define_insn "divsi3"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(div:SI (match_operand:SI 1 "nonmemory_nonsubreg_operand" "")
		 (match_operand:SI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "divsi3 %1, %2 -> %0")

(define_insn "divdi3"
  [(set (match_operand:DI 0 "register_operand" "=r")
	(div:DI (match_operand:DI 1 "nonmemory_nonsubreg_operand" "")
		 (match_operand:DI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "divdi3 %1, %2 -> %0")

(define_insn "divsf3"
  [(set (match_operand:SF 0 "register_operand" "=f")
	(div:SF (match_operand:SF 1 "nonmemory_nonsubreg_operand" "")
		(match_operand:SF 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "divsf3 %1, %2 -> %0")

(define_insn "divdf3"
  [(set (match_operand:DF 0 "register_operand" "=e")
	(div:DF (match_operand:DF 1 "nonmemory_nonsubreg_operand" "")
		(match_operand:DF 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "divdf3 %1, %2 -> %0")


;; Unsigned Division
(define_insn "udivqi3"
  [(set (match_operand:QI 0 "register_operand" "=r")
	(udiv:QI (match_operand:QI 1 "nonmemory_nonsubreg_operand" "" )
		 (match_operand:QI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "udivqi3 %1, %2 -> %0")

(define_insn "udivhi3"
  [(set (match_operand:HI 0 "register_operand" "=r")
	(udiv:HI (match_operand:HI 1 "nonmemory_nonsubreg_operand" "" )
		 (match_operand:HI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "udivhi3 %1, %2 -> %0")

(define_insn "udivsi3"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(udiv:SI (match_operand:SI 1 "nonmemory_nonsubreg_operand" "" )
		 (match_operand:SI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "udivsi3 %1, %2 -> %0")

(define_insn "udivdi3"
  [(set (match_operand:DI 0 "register_operand" "=r")
	(udiv:DI (match_operand:DI 1 "nonmemory_nonsubreg_operand" "")
		 (match_operand:DI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "udivdi3 %1, %2, %0")

(define_expand "udivpdi3"
  [(set (match_dup 3)
        (zero_extend:DI (match_operand:PDI 1 "nonmemory_nonsubreg_operand" "")))
   (set (match_dup 4)
        (zero_extend:DI (match_operand:PDI 2 "nonmemory_nonsubreg_operand" "")))
   (set (match_dup 5)
        (udiv:DI (match_dup 3) (match_dup 4)))
   (set (match_operand:PDI 0 "register_operand" "=r")
        (truncate:PDI (match_dup 5)))]
  ""
  "
{
  operands[3] = gen_reg_rtx(DImode);
  operands[4] = gen_reg_rtx(DImode);
  operands[5] = gen_reg_rtx(DImode);
}")



;; Modulus instructions

(define_insn "modqi3"
  [(set (match_operand:QI 0 "register_operand" "=r")
	(mod:QI (match_operand:QI 1 "nonmemory_nonsubreg_operand" "")
		 (match_operand:QI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "modqi3 %1, %2 -> %0")


(define_insn "modhi3"
  [(set (match_operand:HI 0 "register_operand" "=r")
	(mod:HI (match_operand:HI 1 "nonmemory_nonsubreg_operand" "")
		 (match_operand:HI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "modhi3 %1, %2 -> %0")


(define_insn "modsi3"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(mod:SI (match_operand:SI 1 "nonmemory_nonsubreg_operand" "")
		 (match_operand:SI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "modsi3 %1, %2 -> %0")


(define_insn "moddi3"
  [(set (match_operand:DI 0 "register_operand" "=r")
	(mod:DI (match_operand:DI 1 "nonmemory_nonsubreg_operand" "")
		 (match_operand:DI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "moddi3 %1, %2 -> %0")

(define_insn "modsf3"
  [(set (match_operand:SF 0 "register_operand" "=f")
	(mod:SF (match_operand:SF 1 "nonmemory_nonsubreg_operand" "")
		(match_operand:SF 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "modsf3 %1, %2 -> %0")

(define_insn "moddf3"
  [(set (match_operand:DF 0 "register_operand" "=e")
	(mod:DF (match_operand:DF 1 "nonmemory_nonsubreg_operand" "")
		(match_operand:DF 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "moddf3 %1, %2 -> %0")


;; Unsigned Modulus
(define_insn "umodqi3"
  [(set (match_operand:QI 0 "register_operand" "=r")
	(umod:QI (match_operand:QI 1 "nonmemory_nonsubreg_operand" "" )
		 (match_operand:QI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "umodqi3 %1, %2 -> %0")

(define_insn "umodhi3"
  [(set (match_operand:HI 0 "register_operand" "=r")
	(umod:HI (match_operand:HI 1 "nonmemory_nonsubreg_operand" "" )
		 (match_operand:HI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "umodhi3 %1, %2 -> %0")

(define_insn "umodsi3"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(umod:SI (match_operand:SI 1 "nonmemory_nonsubreg_operand" "" )
		 (match_operand:SI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "umodsi3 %1, %2 -> %0")

(define_insn "umoddi3"
  [(set (match_operand:DI 0 "register_operand" "=r")
	(umod:DI (match_operand:DI 1 "nonmemory_nonsubreg_operand" "")
		 (match_operand:DI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "umoddi3 %1, %2, %0")

;; LLVM doesn't have a NEG instruction, but it does have a SUB instruction.  Use
;; it instead.
;;

(define_expand "negpdi3"
  [(set (match_dup 2)
        (zero_extend:DI (match_operand:PDI 1 "nonmemory_nonsubreg_operand" "")))
   (set  (match_dup 3)
         (minus:DI (const_int 0) (match_dup 2)))
   (set (match_operand:PDI 0 "register_operand" "=r")
        (truncate:PDI (match_dup 3)))]
  ""
  "
{
  operands[2] = gen_reg_rtx(DImode);
  operands[3] = gen_reg_rtx(DImode);
}")

(define_insn "negdi2"
  [(set (match_operand:DI 0 "register_operand" "=r")
	(minus:DI (const_int 0)
                  (match_operand:DI 1 "nonmemory_nonsubreg_operand" "")))]
  ""
  "")

(define_insn "negsi2"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(minus:SI (const_int 0)
                  (match_operand:SI 1 "nonmemory_nonsubreg_operand" "")))]
  ""
  "")

(define_insn "neghi2"
  [(set (match_operand:HI 0 "register_operand" "=r")
	(minus:HI (const_int 0)
                  (match_operand:HI 1 "nonmemory_nonsubreg_operand" "")))]
  ""
  "")

(define_insn "negqi2"
  [(set (match_operand:QI 0 "register_operand" "=r")
	(minus:QI (const_int 0)
                  (match_operand:QI 1 "nonmemory_nonsubreg_operand" "")))]
  ""
  "")

(define_insn "negdf2"
  [(set (match_operand:DF 0 "register_operand" "=e")
	(minus:DF (const_int 0)
                  (match_operand:DF 1 "nonmemory_nonsubreg_operand" "e")))]
  ""
  "")

(define_insn "negsf2"
  [(set (match_operand:SF 0 "register_operand" "=f")
	(minus:SF (const_int 0)
                  (match_operand:SF 1 "nonmemory_nonsubreg_operand" "f")))]
  ""
  "")


;;- Boolean instructions

(define_insn "anddi3"
  [(set (match_operand:DI 0 "register_operand" "=r")
	(and:DI (match_operand:DI 1 "nonmemory_nonsubreg_operand" "")
		(match_operand:DI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "anddi3 %1, %2, %0")

(define_insn "andsi3"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(and:SI (match_operand:SI 1 "nonmemory_nonsubreg_operand" "")
		(match_operand:SI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "andsi3 %1, %2, %0")

(define_insn "andhi3"
  [(set (match_operand:HI 0 "register_operand" "=r")
	(and:HI (match_operand:HI 1 "nonmemory_nonsubreg_operand" "")
		(match_operand:HI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "andhi3 %1, %2, %0")

(define_insn "andqi3"
  [(set (match_operand:QI 0 "register_operand" "=r")
	(and:QI (match_operand:QI 1 "nonmemory_nonsubreg_operand" "")
		(match_operand:QI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "andqi3 %1, %2, %0")



(define_insn "iordi3"
  [(set (match_operand:DI 0 "register_operand" "=r")
	(ior:DI (match_operand:DI 1 "nonmemory_nonsubreg_operand" "")
		(match_operand:DI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "iordi3 %1, %2, %0")

(define_insn "iorsi3"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(ior:SI (match_operand:SI 1 "nonmemory_nonsubreg_operand" "")
		(match_operand:SI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "iorsi3 %1, %2, %0")

(define_insn "iorhi3"
  [(set (match_operand:HI 0 "register_operand" "=r")
	(ior:HI (match_operand:HI 1 "nonmemory_nonsubreg_operand" "")
		(match_operand:HI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "iorhi3 %1, %2, %0")

(define_insn "iorqi3"
  [(set (match_operand:QI 0 "register_operand" "=r")
	(ior:QI (match_operand:QI 1 "nonmemory_nonsubreg_operand" "")
		(match_operand:QI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "iorqi3 %1, %2, %0")


(define_insn "xordi3"
  [(set (match_operand:DI 0 "register_operand" "=r")
	(xor:DI (match_operand:DI 1 "nonmemory_nonsubreg_operand" "")
		(match_operand:DI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "xordi3 %1, %2, %0")

(define_insn "xorsi3"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(xor:SI (match_operand:SI 1 "nonmemory_nonsubreg_operand" "")
		(match_operand:SI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "xorsi3 %1, %2, %0")

(define_insn "xorhi3"
  [(set (match_operand:HI 0 "register_operand" "=r")
	(xor:HI (match_operand:HI 1 "nonmemory_nonsubreg_operand" "")
		(match_operand:HI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "xorhi3 %1, %2, %0")

(define_insn "xorqi3"
  [(set (match_operand:QI 0 "register_operand" "=r")
	(xor:QI (match_operand:QI 1 "nonmemory_nonsubreg_operand" "")
		(match_operand:QI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "xorqi3 %1, %2, %0")

;; LLVM doesn't have a NOT instruction, but it does have a XOR instruction.  Use
;; it instead.
;;
(define_expand "one_cmpldi2"
  [(set (match_operand:DI 0 "register_operand" "=r")
	(xor:DI (match_operand:DI 1 "nonmemory_nonsubreg_operand" "")
                (const_int -1)))]
  ""
  "")

(define_expand "one_cmplsi2"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(xor:SI (match_operand:SI 1 "nonmemory_nonsubreg_operand" "")
                (const_int -1)))]
  ""
  "")

(define_expand "one_cmplhi2"
  [(set (match_operand:HI 0 "register_operand" "=r")
	(xor:HI (match_operand:HI 1 "nonmemory_nonsubreg_operand" "")
                (const_int -1)))]
  ""
  "")

(define_expand "one_cmplqi2"
  [(set (match_operand:QI 0 "register_operand" "=r")
	(xor:QI (match_operand:QI 1 "nonmemory_nonsubreg_operand" "")
                (const_int -1)))]
  ""
  "")




;;- arithmetic shift instructions

(define_insn "ashlqi3"
  [(set (match_operand:QI 0 "register_operand" "=r")
	(ashift:QI (match_operand:QI 1 "nonmemory_nonsubreg_operand" "")
		   (match_operand:QI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "ashlqi3 %1, %2 -> %0")

(define_insn "ashlhi3"
  [(set (match_operand:HI 0 "register_operand" "=r")
	(ashift:HI (match_operand:HI 1 "nonmemory_nonsubreg_operand" "")
		   (match_operand:QI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "ashlhi3 %1, %2 -> %0")

(define_insn "ashlsi3"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(ashift:SI (match_operand:SI 1 "nonmemory_nonsubreg_operand" "")
		   (match_operand:QI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "ashlsi3 %1, %2 -> %0")

(define_insn "ashldi3"
  [(set (match_operand:DI 0 "register_operand" "=r")
	(ashift:DI (match_operand:DI 1 "nonmemory_nonsubreg_operand" "")
		   (match_operand:QI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "ashldi3 %1, %2 -> %0")

(define_expand "ashlpdi3"
  [(set (match_dup 3)
        (zero_extend:DI (match_operand:PDI 1 "nonmemory_nonsubreg_operand" "")))
   (set  (match_dup 4)
         (ashift:DI (match_dup 3) 
                    (match_operand:QI 2 "nonmemory_nonsubreg_operand" "")))
   (set (match_operand:PDI 0 "register_operand" "=r")
        (truncate:PDI (match_dup 4)))]
  ""
  "
{
  operands[3] = gen_reg_rtx(DImode);
  operands[4] = gen_reg_rtx(DImode);
}")



;; ashr

(define_insn "ashrqi3"
  [(set (match_operand:QI 0 "register_operand" "=r")
	(ashiftrt:QI (match_operand:QI 1 "nonmemory_nonsubreg_operand" "")
		     (match_operand:QI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "ashrqi3 %1, %2 -> %0")

(define_insn "ashrhi3"
  [(set (match_operand:HI 0 "register_operand" "=r")
	(ashiftrt:HI (match_operand:HI 1 "nonmemory_nonsubreg_operand" "")
		     (match_operand:QI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "ashrhi3 %1, %2 -> %0")

(define_insn "ashrsi3"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(ashiftrt:SI (match_operand:SI 1 "nonmemory_nonsubreg_operand" "")
		     (match_operand:QI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "ashrsi3 %1, %2 -> %0")

(define_insn "ashrdi3"
  [(set (match_operand:DI 0 "register_operand" "=r")
	(ashiftrt:DI (match_operand:DI 1 "nonmemory_nonsubreg_operand" "")
		     (match_operand:QI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "ashrdi3 %1, %2 -> %0")

(define_expand "ashrpdi3"
  [(set (match_dup 3)
        (zero_extend:DI (match_operand:PDI 1 "nonmemory_nonsubreg_operand" "")))
   (set  (match_dup 4)
         (ashiftrt:DI (match_dup 3) 
                      (match_operand:QI 2 "nonmemory_nonsubreg_operand" "")))
   (set (match_operand:PDI 0 "register_operand" "=r")
        (truncate:PDI (match_dup 4)))]
  ""
  "
{
  operands[3] = gen_reg_rtx(DImode);
  operands[4] = gen_reg_rtx(DImode);
}")


(define_insn "lshrqi3"
  [(set (match_operand:QI 0 "register_operand" "=r")
	(lshiftrt:QI (match_operand:QI 1 "nonmemory_nonsubreg_operand" "")
		     (match_operand:QI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "lshrqi3 %1, %2 -> %0")

(define_insn "lshrhi3"
  [(set (match_operand:HI 0 "register_operand" "=r")
	(lshiftrt:HI (match_operand:HI 1 "nonmemory_nonsubreg_operand" "")
		     (match_operand:QI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "lshrhi3 %1, %2 -> %0")

(define_insn "lshrsi3"
  [(set (match_operand:SI 0 "register_operand" "=r")
	(lshiftrt:SI (match_operand:SI 1 "nonmemory_nonsubreg_operand" "")
		     (match_operand:QI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "lshrsi3 %1, %2 -> %0")

(define_insn "lshrdi3"
  [(set (match_operand:DI 0 "register_operand" "=r")
	(lshiftrt:DI (match_operand:DI 1 "nonmemory_nonsubreg_operand" "")
		     (match_operand:QI 2 "nonmemory_nonsubreg_operand" "")))]
  ""
  "lshrdi3 %1, %2 -> %0")

(define_expand "lshrpdi3"
  [(set (match_dup 3)
        (zero_extend:DI (match_operand:PDI 1 "nonmemory_nonsubreg_operand" "")))
   (set  (match_dup 4)
         (lshiftrt:DI (match_dup 3) 
                      (match_operand:QI 2 "nonmemory_nonsubreg_operand" "")))
   (set (match_operand:PDI 0 "register_operand" "=r")
        (truncate:PDI (match_dup 4)))]
  ""
  "
{
  operands[3] = gen_reg_rtx(DImode);
  operands[4] = gen_reg_rtx(DImode);
}")



\f
;; Unconditional and other jump instructions
;; On the Sparc, by setting the annul bit on an unconditional branch, the
;; following insn is never executed.  This saves us a nop.  Dbx does not
;; handle such branches though, so we only use them when optimizing.
(define_insn "jump"
  [(set (pc) (label_ref (match_operand 0 "" "")))]
  ""
  "*
{
  /* TurboSparc is reported to have problems with
     with
	foo: b,a foo
     i.e. an empty loop with the annul bit set.  The workaround is to use 
        foo: b foo; nop
     instead.  */

  return \"ba,pt%*\\t%%xcc, %l0%(\";
}")

;(define_expand "tablejump"
;  [(parallel [(set (pc) (match_operand 0 "register_operand" "r"))
;	      (use (label_ref (match_operand 1 "" "")))])]
;  ""
;  "
;{
;  if (GET_MODE (operands[0]) != CASE_VECTOR_MODE)
;    abort ();
;}")

;(define_insn "*tablejump_sp"
;  [(set (pc) (match_operand:DI 0 "address_operand" "p"))
;   (use (label_ref (match_operand 1 "" "")))]
;  ""
;  "br %a0%#")

;;- jump to subroutine
(define_expand "call"
  ;; Note that this expression is not used for generating RTL.
  ;; All the RTL is generated explicitly below.
  [(call (match_operand 0 "call_operand" "")
	 (match_operand 3 "" "i"))]
  ;; operands[2] is next_arg_register
  ;; operands[3] is struct_value_size_rtx.
  ""
  "
{ emit_call_insn(gen_rtx_CALL(VOIDmode, operands[0], const0_rtx));
  DONE;
}")

;; We can't use the same pattern for these two insns, because then registers
;; in the address may not be properly reloaded.

(define_insn "*call_address_sp64"
  [(call (mem:PDI (match_operand:PDI 0 "address_operand" "p"))
	 (match_operand 1 "" ""))]
  ;;- Do not use operand 1 for most machines.
  ""
  "call %a0, %1%#")

(define_insn "*call_symbolic"
  [(call (mem:PDI (match_operand:PDI 0 "symbolic_operand" "s"))
	 (match_operand 1 "" ""))]
  ;;- Do not use operand 1 for most machines.
  ""
  "call %a0, %1%#")

(define_expand "call_value"
  ;; Note that this expression is not used for generating RTL.
  ;; All the RTL is generated explicitly below.
  [(set (match_operand 0 "nonmemory_nonsubreg_operand" "=rf")
	(call (match_operand 1 "" "")
	      (match_operand 4 "" "")))]
  ;; operand 2 is stack_size_rtx
  ;; operand 3 is next_arg_register
  ""
  "
{
  if (GET_MODE (operands[1]) != FUNCTION_MODE)
    abort ();
  emit_call_insn(gen_rtx_SET (VOIDmode, operands[0],
                              gen_rtx_CALL (VOIDmode, operands[1], const0_rtx)));
  DONE;
}")

(define_insn "*call_value_address"
  [(set (match_operand 0 "" "")
	(call (mem:PDI (match_operand:PDI 1 "address_operand" "p"))
	      (match_operand 2 "" "")))]
  ;;- Do not use operand 2 for most machines.
  ""
  "call\\t%a1, %2%#")

(define_insn "*call_value_symbolic"
  [(set (match_operand 0 "" "")
	(call (mem:PDI (match_operand:PDI 1 "symbolic_operand" "s"))
	      (match_operand 2 "" "")))]
  ;;- Do not use operand 2 for most machines.
  ""
  "call\\t%a1, %2%#")

(define_expand "untyped_call"
  [(parallel [(call (match_operand 0 "" "")
		    (const_int 0))
	      (match_operand 1 "" "")
	      (match_operand 2 "" "")])]
  ""
  "
{
  int i;

  /* Pass constm1 to indicate that it may expect a structure value, but
     we don't know what size it is.  */
  emit_call_insn (GEN_CALL (operands[0], const0_rtx, NULL, constm1_rtx));

  for (i = 0; i < XVECLEN (operands[2], 0); i++)
    {
      rtx set = XVECEXP (operands[2], 0, i);
      emit_move_insn (SET_DEST (set), SET_SRC (set));
    }

  DONE;
}")


;; Prepare to return any type including a structure value.

(define_expand "untyped_return"
  [(match_operand:BLK 0 "memory_operand" "")
   (match_operand 1 "" "")]
  ""
  "
{
  rtx valreg1 = gen_rtx_REG (DImode, 24);
  rtx valreg2 = gen_rtx_REG (DFmode, 32);
  rtx result = operands[0];

  /* Reload the function value registers.  */
  emit_move_insn (valreg1, change_address (result, DImode, XEXP (result, 0)));
  emit_move_insn (valreg2,
		  change_address (result, DFmode,
				  plus_constant (XEXP (result, 0), 8)));

  /* Put USE insns before the return.  */
  emit_insn (gen_rtx_USE (VOIDmode, valreg1));
  emit_insn (gen_rtx_USE (VOIDmode, valreg2));

  /* Construct the return.  */
  expand_null_return ();

  DONE;
}")

\f

(define_insn "nop"
  [(const_int 0)]
  ""
  "nop")

(define_expand "indirect_jump"
  [(set (pc) (match_operand 0 "address_operand" "p"))]
  ""
  "")

(define_insn "*branch_sp64"
  [(set (pc) (match_operand:PDI 0 "address_operand" "p"))]
  ""
  "br %a0%#
")

(define_expand "nonlocal_goto"
  [(match_operand:SI 0 "general_operand" "")
   (match_operand:SI 1 "general_operand" "")
   (match_operand:SI 2 "general_operand" "")
   (match_operand:SI 3 "" "")]
  ""
  "
{
  rtx fp = operands[1];
  rtx stack = operands[2];
  rtx lab = operands[3];
  rtx labreg;

  /* Load the fp value for the containing fn into %fp.  This is needed
     because STACK refers to %fp.  Note that virtual register instantiation
     fails if the virtual %fp isn't set from a register.  */
  if (GET_CODE (fp) != REG)
    fp = force_reg (Pmode, fp);
  emit_move_insn (virtual_stack_vars_rtx, fp);

  /* Find the containing function's current nonlocal goto handler,
     which will do any cleanups and then jump to the label.  */
  labreg = gen_rtx_REG (Pmode, 8);
  emit_move_insn (labreg, lab);

  /* Restore %fp from stack pointer value for containing function.
     The restore insn that follows will move this to %sp,
     and reload the appropriate value into %fp.  */
  emit_move_insn (frame_pointer_rtx, stack);

  /* USE of frame_pointer_rtx added for consistency; not clear if
     really needed.  */
  /*emit_insn (gen_rtx_USE (VOIDmode, frame_pointer_rtx));*/
  emit_insn (gen_rtx_USE (VOIDmode, stack_pointer_rtx));

  emit_insn (gen_rtx_USE (VOIDmode, static_chain_rtx));
  emit_jump_insn (gen_goto_handler_and_restore (labreg));
  emit_barrier ();
  DONE;
}")

(define_insn "goto_handler_and_restore"
  [(unspec_volatile [(match_operand 0 "register_operand" "=r")] 2)]
  "GET_MODE (operands[0]) == Pmode"
  "jmp\\t%0+0\\n\\trestore")


;;; Special allocate_stack definition.  This causes alloca instructions to be
;;; turned into calls to __llvm_builtin_alloca, which is recognized by the LLVM
;;; backend, and turned into alloca instructions.
;;;
(define_expand "allocate_stack"
  [(match_operand:PDI 0 "register_operand" "=r")
   (match_operand:PDI 1 "register_operand" "")]
   ""
   "
{
  rtx Dest = operands[0], Amount = operands[1];
  emit_library_call_value(gen_rtx(SYMBOL_REF, Pmode, 
                          \"__llvm_builtin_alloca\"), Dest,
                          /*Pure fn call */ 2, PDImode, 1, Amount, DImode);
  DONE;
}")




;;(define_insn "*goto_handler_and_restore_v9_sp64"
;;  [(unspec_volatile [(match_operand:DI 0 "register_operand" "=r,r")
;;		     (match_operand:DI 1 "register_operand" "=r,r")
;;		     (match_operand:SI 2 "const_int_operand" "n,n")] 3)]
;;  ""
;;  "@
;;   return\\t%0+0\\n\\tmov\\t%2, %Y1
;;   sethi\\t%%hi(%2), %1\\n\\treturn\\t%0+0\\n\\tor\\t%Y1, %%lo(%2), %Y1")

;; For __builtin_setjmp we need to flush register windows iff the function
;; calls alloca as well, because otherwise the register window might be
;; saved after %sp adjustement and thus setjmp would crash
(define_expand "builtin_setjmp_setup"
  [(match_operand 0 "register_operand" "r")]
  ""
  "
{
  emit_insn (gen_do_builtin_setjmp_setup ());
  DONE;
}")

(define_insn "do_builtin_setjmp_setup"
  [(unspec_volatile [(const_int 0)] 5)]
  ""
  "*
{
  if (!current_function_calls_alloca)
    return \"\";
  return \"flushw\";
}")

;; Pattern for use after a setjmp to store FP and the return register
;; into the stack area.

(define_expand "setjmp"
  [(const_int 0)]
  ""
  "
{
  emit_insn (gen_setjmp_64 ());
  DONE;
}")

(define_expand "setjmp_32"
  [(set (mem:SI (plus:SI (reg:SI 14) (const_int 56))) (match_dup 0))
   (set (mem:SI (plus:SI (reg:SI 14) (const_int 60))) (reg:SI 31))]
  ""
  "
{ operands[0] = frame_pointer_rtx; }")

(define_expand "setjmp_64"
  [(set (mem:DI (plus:DI (reg:DI 14) (const_int 112))) (match_dup 0))
   (set (mem:DI (plus:DI (reg:DI 14) (const_int 120))) (reg:DI 31))]
  ""
  "
{ operands[0] = frame_pointer_rtx; }")

\f

;;;; We need to reload %l7 for -mflat -fpic,
;;;; otherwise %l7 should be preserved simply
;;;; by loading the function's register window
;;(define_expand "exception_receiver"
;;  [(const_int 0)]
;;  "flag_pic"
;;  "
;;{
;;  load_pic_register ();
;;  DONE;
;;}")

;;;; Likewise
;;(define_expand "builtin_setjmp_receiver"
;;  [(label_ref (match_operand 0 "" ""))]
;;  "flag_pic"
;;  "
;;{
;;  load_pic_register ();
;;  DONE;
;;}")
\f
(define_insn "trap"
  [(trap_if (const_int 1) (const_int 5))]
  ""
  "ta\\t5")

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2002-12-11 16:01 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-12-10 23:20 RTL to Simple Three instruction code Aditya Kanade
2002-12-10 23:29 ` Peter Barada
2002-12-11  7:17 ` Diego Novillo
2002-12-11  7:59   ` Michael S. Zick
2002-12-11  9:00     ` Diego Novillo
2002-12-10 23:36 Chris Lattner
2002-12-10 23:30 ` Chris Lattner

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).