RTL to Simple Three instruction code
Chris Lattner
sabre@nondot.org
Tue Dec 10 23:30:00 GMT 2002
>>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/
-------------- next part --------------
;;- 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.
;; 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")
;; 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)))]
""
"")
;; 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!)
")
;; 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")
;; 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")
;; 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")
;;- 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")
;;- 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")
;; 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")
;; 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")
;;- 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")
;; 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);
}")
;; 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;
}")
(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; }")
;;;; 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;
;;}")
(define_insn "trap"
[(trap_if (const_int 1) (const_int 5))]
""
"ta\\t5")
More information about the Gcc
mailing list