Files
linguist/samples/GCC Machine Description/pdp10.md
2016-07-11 18:41:01 +02:00

6666 lines
198 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;;- Machine description for the PDP-10.
;; Copyright (C) 2001, 2002 Lars Brinkhoff.
;; Contributed by Lars Brinkhoff <lars@nocrew.org>, funded by XKL, LLC.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Index
;; Front Page
;; Index
;; Constraints for Immediate Operands
;; To-do List
;; Instruction Wish-List
;; Attributes
;; length, skip, reorg_type
;; Unspec Usage
;; UNSPEC_ADJSP, UNSPEC_ADJBP, UNSPEC_ADDRESS, UNSPEC_FFO, UNSPEC_SUBBP,
;; VUNSPEC_BLT, VUNSPEC_FSC, VUNSPEC_XBLT, VUNSPEC_MOVSLJ, VUNSPEC_MOVST
;; Constants
;; RIGHT_HALF, LEFT_HALF, SIGNBIT, SP_REGNUM
;; Optimizations
;; Data Movement
;; LDB, ILDB, (LDBI), LDBE, ILDBE, (LDBEI), DPB, IDPB, (DPBI),
;; HRR, HRL, HLR, HLL, HRRM, HRLM, HLRM, HLLM,
;; HRRZ, HRLZ, HLRZ, HLLZ, HRRE, HRLE, HLRE, HLLE,
;; SETZM, SETOM,
;; MOVE, MOVEI, MOVSI, HRLOI, HRROI, MOVEM,
;; MOVS, EXCH, SETZB,
;; DMOVE, DMOVEM,
;; BLT, XBLT, (MOVSLJ), (MOVST), (CMPS)
;; Conditional Data Movement
;; SKIPL, SKIPE, SKIPLE, SKIPGE, SKIPN, SKIPG,
;; TDZA
;; Integer Arithmetic
;; AOS, SOS,
;; ADD, ADDI, ADDM, ADDB, DADD,
;; SUB, SUBI, SUBM, SUBB, DSUB,
;; IMUL, IMULI, IMULM, IMULB, MUL, MULI, MULM, MULB, DMUL,
;; IDIV, IDIVI, IDIVM, DIV, DIVI, DIVM, DDIV,
;; UIDIV, UIDIVI, UIDIVM, UIMOD, UIMODI, UIMODM,
;; MOVN, MOVNM, MOVNS, MOVNI, DMOVN, DMOVNM,
;; MOVM, MOVMM, MOVMS,
;; FFS
;; Integer Conversions
;; ANDI, HRRZ, SEXT, HRRE, ANDI, HRR
;; Shifting and Rotating
;; LSH, LSHC, ASH, ASHC, ROT, ROTC
;; Logical Operations
;; AND, ANDI, ANDM, ANDB, TLZ, ANDCMI,
;; ANDCA, ANDCAI, ANDCAM, ANDCAB, ANDCBI,
;; ANDCM, ANDCMM, ANDCMB,
;; XOR, XORI, XORM, XORB, TLC, EQVI,
;; IOR, IORI, IORM, IORB, TLO, ORCMI,
;; ANDCB, ANDCBM, ANDCBB,
;; EQV, EQVM, EQVB,
;; SETCA, SETCAM, SETCAB,
;; SETCM, SETCMM, SETCMB,
;; ORCA, ORCAI, ORCAM, ORCAB, ORCBI,
;; ORCM, ORCMM, ORCMB,
;; ORCB, ORCBM, ORCBB
;; Floating-point Arithmetic
;; FADR, FADRI, FADRM, FADRB, DFAD, GFAD,
;; FSBR, FSBRI, FSBRM, FSBRB, DFSB, GFSB,
;; MOVM, MOVMM, MOVMS,
;; MOVN, MOVNM, MOVNS, DMOVN, DMOVNM,
;; FMPR, FMPRI, FMPRM, FMPRB, DFMP, GFMP,
;; FDVR, FDVRI, FDVRM, FDVRB, DFDV, GFDV,
;; SQRT, DSQRT, GSQRT,
;; FSC, DFSC, GFSC
;; Floating-point Conversions
;; FIX, DFIX, GFIX, DDFIX, GDFIX,
;; FLTR, DFLTR, GFLTR, DDFLTR, DGFLTR,
;; GSNGL, GDBLE
;; Pointer Arithmetic
;; IBP, ADJBP, SUBBP
;; Unconditional Jumps
;; JFCL, JRST, PUSHJ
;; Conditional Jumps
;; TRNE, TLNE, TDNE, TRNN, TLNN, TDNN, TLZN,
;; JUMP, SKIP, CAI, CAM,
;; SOJ, SOS, AOJ, AOS,
;; JFFO, CMPBP
;; Function prologue and epilogue
;; POPJ, ADJSP, PUSH, POP
;; Peepholes
;; Miscellaneous
;;
;; Instructions in parentheses are either commented out or not
;; generated by the compiler.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Constraints for Immediate Operands
;; 'G' Any valid immediate floating-point constant.
;; 'I' 0 .. 262143
;; 'J' -262143 .. 0
;; 'K' -131072 .. 131071
;; 'L' xxxxxx,,000000 (MOVSI, TLN, TLO, TLC)
;; 'M' -1
;; 'N' xxxxxx,,777777 (HRLOI, TLZ)
;; 'O' 0
;; 'P' 777777,,xxxxxx (HRROI, ORCMI, ANDCBI, ANDCMI)
;; 'Q' 1
;; 'R' Floating-point zero.
;; 'S' Local symbol.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; To-do List
;; Use peep2_reg_dead_p in peepholes.
;; Unsigned multiplication.
;;
;; mul 1,3 ; multiply AC1 by AC3
;; lsh 2,1
;; lshc 1,-1 ; result in AC2
;; 71-bit arithmetic.
;;
;; Addition, subtraction, multiplication, division, arithmetic shift:
;; supported in hardware.
;;
;; Logical shift (left or right).
;;
;; lsh 2,-1
;; lshc 1,3
;; lsh 2,1
;; 72-bit arithmetic.
;;
;; Addition 72 x 72 -> 72.
;;
;; jfcl 17,.+1 ; add AC1 and AC2 to AC3 and AC4
;; add 2,4
;; jcry0 [aoja 1,.+1]
;; add 1,3 ; result in AC1 and AC2
;;
;; Subtraction 72 x 72 -> 72.
;;
;; jfcl 17,.+1 ; add AC1 and AC2 to AC3 and AC4
;; sub 2,4
;; jcry0 .+2
;; subi 1,1
;; sub 1,3 ; result in AC1 and AC2
;;
;; Negation 72 -> 72.
;;
;; setcm 1,3
;; movn 2,4
;; jumpe 2,[aoja 1,.+1]
;;
;; ; to self
;; setca 1,
;; jumpe 2,[aoja 1,.+2]
;; movn 2,2
;;
;; Magnitude 72 -> 72.
;;
;; ; conditional negation
;; jumpge 1,.+4
;; setca 1,
;; jumpe 2,[aoja 1,.+2]
;; movn 2,2
;;
;; ; mask = x >> 71 (arithmetic shift)
;; ; y = (x ^ mask) - mask
;; move 3,1
;; ash 1,-43 ; shortcut
;; xor 1,3
;; xor 2,3
;; jfcl 17,.+1
;; sub 2,3
;; jcry0 [aoja 1,.+1]
;;
;; Signed right shift 72 -> 72.
;;
;; Variable amount:
;;
;; ; only works if n <= 35
;; movn 4,3 ; operand in AC1:AC2, shift amount in AC3
;; lshc 1,4
;; lsh 1,3
;; ash 1,4 ; result in AC1:AC2
;;
;; ; loop
;; jumple 3,.+5
;; lshc 1,-1
;; tlne 1,200000
;; tlo 1,400000
;; sojg 3,.-3
;;
;; ; only works if n <= 70
;; tlnn 1,400000
;; tdza 4,4
;; movsi 4,400000
;; movei 5,0
;; ashc 4,3
;; lsh 5,1
;; lshc 1,3
;; ior 1,4
;; ior 2,5
;;
;; Fixed amount:
;;
;; lshc 1,-n
;; tlne 1,mask1
;; tlo 1,mask2
;;
;; skipge 1 ; or cail 1,0 or jumpge 1,.+2 or tlne 1,400000
;; iori 2,<2^n-1>
;; rotc 1,-n
;;
;; Signed multiplication 36 x 36 -> 72.
;;
;; jfcl .+1 ; multiply AC1 by AC3
;; mul 1,3
;; lsh 2,1
;; jov [movsi 1,200000
;; jrst .+4]
;; lshc 1,-1
;; tlne 1,200000
;; tlo 1,400000 ; result in AC1 and AC2
;;
;; mul 1,3
;; lsh 2,1
;; jumpe 2,[cam 1,[400000000000]
;; jrst .+1
;; movsi 1,200000
;; jrst .+4]
;; lshc 1,-1
;; tlne 1,200000
;; tlo 1,400000 ; result in AC1 and AC2
;;
;; ...
;; lshc 1,-1
;; lsh 1,1
;; ash 1,-1 ; result in AC1 and AC2
;;
;; ...
;; skipge 1
;; iori 2,1
;; rotc 1,-1 ; result in AC1 and AC2
;;
;; jfcl .+1 ; multiply AC1 by AC3
;; mul 1,3
;; jov [movsi 1,200000
;; movei 2,0
;; jrst .+5]
;; trne 1,1
;; tloa 2,400000
;; tlz 2,400000
;; ash 1,-1 ; result in AC1 and AC2
;;
;; 377777,,777777 ^ 2 = 177777,,777777 000000,,000001
;; -400000,,000000 * 377777,,777777 = -177777,,777777 400000,,000000
;; (= 600000,,000000 400000,,000000)
;; -400000,,000000 ^ 2 = 200000,,000000 000000,,000000
;; -400000,,000000 * -1 = 000000,,000000 400000,,000000
;; -000000,,000001 ^ 2 = 000000,,000000 000000,,000001
;; -000000,,000001 * 000000,,000001 = -000000,,000000 000000,,000001
;; (= 777777,,777777 777777,,777777)
;; -000000,,000001 * 000001,,000001 = -000000,,000000 000001,,000001
;; (= 777777,,777777 777776,,777777)
;;
;; Signed high part multiplication 36 x 36 -> 36.
;;
;; jfcl .+1 ; multiply AC1 by AC2
;; mulm 2,1
;; jov [movsi 1,200000
;; jrst .+2]
;; ash 1,-1 ; result in AC1
;;
;; Unsigned multiplication 36 x 36 -> 72.
;;
;; 377777,,777777 ^ 2 = 177777,,777777 000000,,000001
;; 400000,,000000 * 377777,,777777 = 177777,,777777 400000,,000000
;; 400000,,000000 ^ 2 = 200000,,000000 000000,,000000
;; 400000,,000000 * 777777,,777777 = 377777,,777777 400000,,000000
;; 777777,,777777 ^ 2 = 777777,,777776 000000,,000001
;; 777777,,777777 * 000000,,000001 = 000000,,000000 777777,,777777
;; 777777,,777777 * 000001,,000001 = 000001,,000000 777776,,777777
;;
;; Multiplication 72 x 72 -> 72.
;;
;; dmul 1,3 ; multiply AC1 and AC2 by AC3 and AC4
;; lsh 3,1
;; lshc 2,-1
;; lsh 4,1
;; lshc 3,1
;; trne 2,1
;; tlo 3,400000 ; result in AC3 and AC4
;;
;; dmul 1,3
;; lsh 4,1
;; lshc 3,-1
;; lsh 3,2
;; lshc 2,-2
;;
;; Comparisons 72 x 72.
;;
;; ; x == y
;; CAMN x+1,y+1
;; CAME x,y
;; ;here if false
;; TSC, TSO, TSZ. TSNE, TSNN.
;; Ok to negate double-word integer with DMOVN?
;; Answer: perhaps not.
;;
;; If comparison code cares about bit 0 in the second word of a
;; double-word integer, negation has to set the bit to the right
;; value.
;; Converting from double float to single float (truncdfsf2) needs
;; rounding.
;; ANDCMI really faster than TRZ?
;; Add `cmpdi' pattern.
;; Revisit `casesi'.
;; *move_and_skipsi and *move_and_skipsf clobbers accumulator 0. Is
;; it possible to allocate a scratch register?
;; Peepholes for AOSA and SOSA.
;; "Self" half-word instructions.
;; AOBJP, AOBJN?
;; SUBREG of DImode causes bad register allocation:
;; divmodsi4, divmoddi4, expand_builtin_jffo, ffssi.
;; String instructions. Avoid them for now. REG: "None of these is
;; fast. None of these is thoroughly tested. They all require a lot
;; of registers for setup. They are uncharacteristic of other PDP-10
;; instructions."
;; Test-modify-skip instructions?
;; In case anyone would like to play strange games, this could be
;; optimized to use a PUSHJ instruction:
;; static
;; foo (void **p, void *f) FOO:
;; { PUSHJ 1,(2)
;; *++p = &&label; POPJ 17,
;; goto *f;
;; label:
;; return;
;; }
;; And POPJ:
;; static void
;; bar (void **p) BAR:
;; { POPJ 1,
;; goto *p--;
;; }
;; Use JSP to call functions with __attribute__ ((fastcall)) or similar.
;; Historical: KA10 software double precision floating-point.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Instruction Wish-List
;; ILDBE, LDBE - (increment and) load sign-extended byte.
;; LDBI, LDBEI, DPBI - load/deposit byte, then increment.
;; SUBBP - subtract byte pointers.
;; CMPBP - compare byte pointers.
;; SEXT r,n - sign-extend n-bit byte in register r.
;; Clear/set byte.
;; Test byte >0 =0 <0.
;; UIDIV, UDIV, UDDIV - unsigned division (udivsi3, udivdi3).
;; UIMOD, UMOD, UDMOD - unsigned modulo (umodsi3, umoddi3).
;; UJUMP, USKIP, UCAI, UCAM - compare unsigned values.
;; MIN, MAX, UMIN, UMAX - min/max (minsi3, maxsi3, uminsi3, umaxsi3).
;; SQRT, DSQRT, GSQRT - square root (sqrtM2).
;; SIN, DSIN, GSIN - sine function (__builtin_sin).
;; COS, DCOS, GCOS - cosine function (__builtin_cos).
;; Any other mathematical function: TAN, ASIN, ACOS, ATAN, SINH, COSH,
;; TANH, ASINH, ACOSH, ATANH, EXP, LN, LOG2, LOG10, POW, ... All
;; potentially in single, double, and giant versions.
;; FFS - find first set, counting least significant bit first (ffsM2).
;; ?DFIX, DFIXR - Double Floating to Integer (fix_truncdfsi2).
;; ?DFIX, DFIXR - Single Floating to Double Precision Integer (fix_truncsfdi2).
;; DDFIX, DDFIXR - Double Floating to Double Precision Integer (fix_truncdfdi2)
;; ?DFLTR - Double Float and Round (floatsidf2).
;; ?DFLTR - Float Double Precision Integer and Round (floatdisf2).
;; DDFLTR - Double Float Double Precision Integer and Round (floatdidf2).
;; UDFLTR, UGFLTR, ... - Unsigned Float and Round (floatuns...).
;; WAIT - wait for interrupt.
;; XPUSH, XPUSHJ, XPOP, XPOPJ - fast versions for use with a global
;; stack pointer only.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Attributes
;; Length of the instruction, in words.
(define_attr "length" "" (const_int 1))
;; The instruction is a skip instruction.
(define_attr "skip" "no,yes" (const_string "no"))
;; Instruction type used in the machine dependent reorg pass.
(define_attr "reorg_type" "none,ibp,ldb,dpb" (const_string "none"))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Unspec Usage
(define_constants
[(UNSPEC_ADJSP 0) ; ADJSP operation (Pmode):
; Operand 0 is the stack pointer.
; Operand 1 is the adjustment.
(UNSPEC_ADJBP 1) ; ADJBP operation (Pmode):
; Operand 0 is the byte pointer.
; Operand 1 is the adjustment.
(UNSPEC_ADDRESS 2) ; Effective-address calculation (Pmode):
; Operand 0 is the memory operand.
(UNSPEC_FFO 3) ; Find-first-one operation in FFO (SImode):
; Operand 0 is the register.
(UNSPEC_FSC 4) ; FSC operation (SFmode, DFmode):
; Operand 0 is the floating-point value.
; Operand 1 is the scale factor.
(UNSPEC_SHIFT 5) ; Left-shift operation (SImode, Pmode):
; Used to compensate for unnecessary
; shifts generated by pointer arithmetic.
; Operand 0 is the value.
; Operand 1 is the shift count.
(UNSPEC_SHIFTRT 6) ; Right-shift operation (SImode, Pmode):
; Used to compensate for unnecessary
; shifts generated by pointer arithmetic.
; Operand 0 is the value.
; Operand 1 is the shift count.
(UNSPEC_TLNE_TLZA_TLO ; TLNE-TLZA-TLO sequence (SImode):
7) ; Operand 0 is the register.
; Operand 1 is the TLNE operand.
; Operand 2 is the TLZA operand.
; Operand 3 is the TLO operand.
(UNSPEC_SUBBP 8) ; Byte pointer difference (SImode):
; Operand 0 is the first pointer.
; Operand 1 is the second pointer.
(UNSPEC_CMPBP 9) ; Prepare byte pointer for comparison (SImode):
; Operand 0 is the pointer.
(UNSPEC_REAL_ASHIFT 10) ; Arithmetic left shift (SImode, DImode):
; Operand 0 is the value to shift.
; Operand 1 is the amount to shift by.
(UNSPEC_ASH71 11) ; 71-bit arithmetic shift (DImode):
; Operand 0 is the value to shift.
; Operand 1 is the amount to shift by.
(UNSPEC_MUL71 12) ; 71-bit multiplication (DImode):
; Operands 0 and 1 are the multiplicands.
(UNSPEC_SIGN_EXTEND 13) ; Sign extension (SImode):
; Operand 0 is the value to extend.
; Operand 1 is the number of bits to extend.
(UNSPEC_ZERO_EXTEND 14) ; Zero extension (SImode):
; Operand 0 is the value to extend.
; Operand 1 is the number of bits to extend.
(UNSPEC_TRUNCATE 15) ; Truncate (SImode):
; Operand 0 is the value to truncate.
; Operand 1 is the number of bits to trunc.
(UNSPEC_TRNE_TLO 16) ; TLNE-TLO sequence (SImode):
; Operand 0 is the TRNE operand.
; Operand 1 is the TLO operand.
(UNSPEC_ASHC 17) ; ASHC operation (DImode):
; Operand 0 is the value to shift.
; Operand 1 is the amount to shift by.
(UNSPEC_LSHC 18)]) ; ASHC operation (DImode):
; Operand 0 is the value to shift.
; Operand 1 is the amount to shift by.
(define_constants
[(VUNSPEC_BLOCKAGE 0)
(VUNSPEC_BLT 1) ; BLT operation (BLKmode):
; Operand 0 is the source address.
; Operand 1 is the destination address.
; Operand 2 is the block length.
(VUNSPEC_XBLT 2) ; XBLT operation (BLKmode):
; operand 0 is the block length
; operand 1 is the source address
; operand 2 is the destination address
(VUNSPEC_MOVSLJ 3) ; MOVSLJ operation (BLKmode):
; operand 0 is the register block
(VUNSPEC_MOVST 4) ; MOVST operation (BLKmode):
; operand 0 is the register block
(VUNSPEC_CMPS 5)]) ; CMPS operation (BLKmode):
; operand 0 is the register block
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Constants
(define_constants
[(RIGHT_HALF 262143) ; 0000000777777
(LEFT_HALF -262144) ; 0777777000000
(SIGNBIT -34359738368) ; 0400000000000
(FP_REGNUM 13) ; Frame pointer register.
(SP_REGNUM 15)]) ; Stack pointer register.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Optimizations
;; Adding a constant to a word pointer is done fastest by (X)MOVEI
;; op0,const(op1). As a special case, recognize the stack pointer.
(define_insn "MOVEI_sp"
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (reg:SI SP_REGNUM)
(match_operand:SI 1 "const_int_operand" "")))]
""
{
operands[1] = gen_rtx_PLUS (Pmode, stack_pointer_rtx, operands[1]);
/* ADDRESS: ... */
return TARGET_EXTENDED ? "xmovei %0,%a1" : "movei %0,%a1";
})
;; Moving from any word pointer is done fastest by (X)MOVEI op0,(op1).
;; As a special case, recognize the stack pointer.
(define_insn "*move_from_sp"
[(set (match_operand:SI 0 "register_operand" "=r")
(reg:SI SP_REGNUM))]
""
{
/* ADDRESS: ... */
return TARGET_EXTENDED ? "xmovei %0,(17)" : "movei %0,(17)";
})
;; Load scalar signed chars using HRRE.
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(sign_extend:SI
(match_operand:QI 1 "pdp10_maybe_volatile_memory_operand" "m")))]
"MEM_SCALAR_P (operands[1])"
"hrre %0,%W1")
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(sign_extract:SI
(match_operand:SI 1 "pdp10_maybe_volatile_memory_operand" "m")
(const_int 9)
(const_int 27)))]
"MEM_SCALAR_P (operands[1])"
"hrre %0,%1")
(define_insn ""
[(set (match_operand:QI 0 "register_operand" "=r")
(subreg:QI
(zero_extract:SI (match_operand: SI 1 "memory_operand" "m")
(const_int 9)
(const_int 27))
3))]
"MEM_SCALAR_P (operands[1])"
"move %0,%1")
(define_insn ""
[(set (subreg:QI
(zero_extract:SI (match_operand:SI 0 "memory_operand" "+m")
(const_int 9)
(const_int 27))
3)
(match_operand:QI 1 "register_operand" "r"))]
"MEM_SCALAR_P (operands[0])"
"movem %1,%0")
(define_insn ""
[(set (subreg:HI
(zero_extract:SI (match_operand:SI 0 "memory_operand" "+m")
(const_int 18)
(const_int 18))
2)
(match_operand:HI 1 "register_operand" "r"))]
"MEM_SCALAR_P (operands[0])"
"movem %1,%0")
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(subreg:SI (match_operand:QI 1 "memory_operand" "m") 0)
(match_operand 2 "const_int_operand" "")]
UNSPEC_SIGN_EXTEND))]
"MEM_SCALAR_P (operands[1]) && INTVAL (operands[2]) >= 18"
"hrre %0,%W1")
;; Load scalar unsigned chars using MOVE.
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(zero_extend:SI
(match_operand:QI 1 "pdp10_maybe_volatile_memory_operand" "m")))]
"MEM_SCALAR_P (operands[1])"
"move %0,%W1")
; (define_insn ""
; [(set (match_operand:SI 0 "register_operand" "=r")
; (and:SI
;; This could well be a scalar int variable.
; (match_operand:SI 1 "pdp10_maybe_volatile_memory_operand" "m")
; (const_int 511)))]
; "MEM_SCALAR_P (operands[1])"
; "move %0,%W1")
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(subreg:SI (match_operand:QI 1 "memory_operand" "m") 0)
(match_operand 2 "const_int_operand" "")]
UNSPEC_ZERO_EXTEND))]
"MEM_SCALAR_P (operands[1])"
"move %0,%W1")
;; Store scalar chars using MOVEM.
(define_insn ""
[(set (match_operand:QI 0 "pdp10_maybe_volatile_memory_operand" "=m")
(match_operand:QI 1 "register_operand" "r"))]
"MEM_SCALAR_P (operands[0])"
"movem %1,%W0")
(define_insn ""
[(set (match_operand:SI 0 "pdp10_maybe_volatile_memory_operand" "=m")
(sign_extract:SI (match_operand:SI 1 "register_operand" "r")
(const_int 9)
(const_int 27)))]
"MEM_SCALAR_P (operands[0])"
"movem %1,%0")
(define_insn ""
[(set (zero_extract:SI
(match_operand:SI 0 "pdp10_maybe_volatile_memory_operand" "+m")
(const_int 9)
(const_int 27))
(and:SI (match_operand:SI 1 "register_operand" "r")
(const_int 511)))]
"MEM_SCALAR_P (operands[0])"
"movem %1,%0")
(define_insn ""
[(set (match_operand:QI 0 "memory_operand" "=m")
(subreg:QI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
(match_operand 2 "const_int_operand" "")]
UNSPEC_SIGN_EXTEND)
3))]
"MEM_SCALAR_P (operands[0])"
"movem %1,%W0")
(define_insn ""
[(set (match_operand:QI 0 "memory_operand" "=m")
(subreg:QI (unspec:SI [(match_operand:SI 1 "register_operand" "r")
(match_operand 2 "const_int_operand" "")]
UNSPEC_ZERO_EXTEND)
3))]
"MEM_SCALAR_P (operands[0])"
"movem %1,%W0")
;; Load scalar unsigned shorts using MOVE.
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(zero_extend:SI
(match_operand:HI 1 "pdp10_maybe_volatile_memory_operand" "m")))]
"MEM_SCALAR_P (operands[1])"
"move %0,%W1")
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
(subreg:HI
(zero_extract:SI
(match_operand:SI 1 "pdp10_maybe_volatile_memory_operand" "m")
(const_int 18)
(const_int 18))
2))]
"MEM_SCALAR_P (operands[1])"
"move %0,%W1")
; (define_insn ""
; [(set (match_operand:SI 0 "register_operand" "=r")
;; This could well be a scalar int variable.
; (and:SI (match_operand:SI 1 "pdp10_maybe_volatile_memory_operand" "m")
; (const_int RIGHT_HALF)))]
; "MEM_SCALAR_P (operands[1])"
; "move %0,%W1")
;; Load scalar signed shorts using HRRE.
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(sign_extract:SI
(match_operand:SI 1 "pdp10_maybe_volatile_memory_operand" "m")
(const_int 18)
(const_int 18)))]
"MEM_SCALAR_P (operands[1])"
"hrre %0,%1")
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(sign_extend:SI
(match_operand:HI 1 "pdp10_maybe_volatile_memory_operand" "m")))]
"MEM_SCALAR_P (operands[1])"
"hrre %0,%W1")
;; Store scalar shorts using MOVEM.
(define_insn ""
[(set (match_operand:HI 0 "pdp10_maybe_volatile_memory_operand" "=m")
(match_operand:HI 1 "register_operand" "r"))]
"MEM_SCALAR_P (operands[0])"
"movem %1,%W0")
(define_insn ""
[(set (zero_extract:SI
(match_operand:SI 0 "pdp10_maybe_volatile_memory_operand" "+m")
(const_int 18)
(const_int 18))
(and:SI (match_operand:SI 1 "register_operand" "r")
(const_int RIGHT_HALF)))]
"MEM_SCALAR_P (operands[0])"
"movem %1,%0")
(define_insn "*sgeu"
[(set (match_operand:SI 0 "register_operand" "=x")
(ge:SI (xor:SI (match_operand:SI 1 "reg_or_mem_operand" "rm")
(const_int SIGNBIT))
(match_operand:SI 2 "const_int_operand" "")))]
""
{
HOST_WIDE_INT sign = (HOST_WIDE_INT)1 << 35;
operands[2] = gen_int_mode (INTVAL (operands[2]) ^ sign, SImode);
if (INTVAL (operands[2]) & ~(HOST_WIDE_INT)0777777)
return "skipl %0,%1\;%_caml %0,[%2]\;%_%_trna\;%_%_%_tdza %0,%0\;%_%_%_%_movei %0,1";
else
return "skipl %0,%1\;%_cail %0,%2\;%_%_trna\;%_%_%_tdza %0,%0\;%_%_%_%_movei %0,1";
}
[(set_attr "length" "5")])
(define_insn "*sgeu_plus"
[(set (match_operand:SI 0 "register_operand" "=&r")
(ge:SI (xor:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "const_int_operand" ""))
(const_int SIGNBIT))
(match_operand:SI 3 "const_int_operand" "")))]
""
{
HOST_WIDE_INT sign = (HOST_WIDE_INT)1 << 35;
output_asm_insn ("movei %0,0", operands);
operands[2] = gen_int_mode (-INTVAL (operands[2]), SImode);
if (INTVAL (operands[2]) & ~(HOST_WIDE_INT)0777777)
output_asm_insn ("caml %1,[%2]", operands);
else
output_asm_insn ("cail %1,%2", operands);
operands[3] = gen_int_mode ((INTVAL (operands[3]) ^ sign)
- INTVAL (operands[2]), SImode);
if (INTVAL (operands[3]) & ~(HOST_WIDE_INT)0777777)
output_asm_insn ("%_caml %1,[%3]", operands);
else
output_asm_insn ("%_cail %1,%3", operands);
return "%_%_movei %0,1";
}
[(set_attr "length" "4")])
(define_insn "*cbranchgeu"
[(set (pc)
(if_then_else
(ge (xor:SI (match_operand:SI 0 "register_operand" "r")
(const_int SIGNBIT))
(match_operand:SI 1 "const_int_operand" ""))
(label_ref (match_operand 2 "" ""))
(pc)))]
""
{
rtx ops[5];
ops[0] = operands[0];
ops[1] = operands[0];
ops[2] = GEN_INT (0);
ops[3] = operands[1];
ops[4] = operands[2];
return pdp10_output_range_compare (insn, ops, 0);
}
[(set_attr "length" "3")])
(define_insn "*cbranchgeu_mem"
[(set (pc)
(if_then_else
(ge (xor:SI (match_operand:SI 0 "memory_operand" "m")
(const_int SIGNBIT))
(match_operand:SI 1 "const_int_operand" ""))
(label_ref (match_operand 2 "" ""))
(pc)))
(clobber (match_scratch:SI 3 "=x"))]
""
{
rtx ops[5];
ops[0] = operands[3];
ops[1] = operands[0];
ops[2] = GEN_INT (0);
ops[3] = operands[1];
ops[4] = operands[2];
return pdp10_output_range_compare (insn, ops, 0);
}
[(set_attr "length" "4")])
(define_insn "*cbranchgeu_plus"
[(set (pc)
(if_then_else
(ge (xor:SI (plus:SI (match_operand:SI 0 "reg_or_mem_operand" "r")
(match_operand:SI 1 "const_int_operand" ""))
(const_int SIGNBIT))
(match_operand:SI 2 "const_int_operand" ""))
(label_ref (match_operand 3 "" ""))
(pc)))]
""
{
rtx ops[5];
ops[0] = operands[0];
ops[1] = operands[0];
ops[2] = operands[1];
ops[3] = operands[2];
ops[4] = operands[3];
return pdp10_output_range_compare (insn, ops, 0);
}
[(set_attr "length" "3")])
(define_insn "*sltu"
[(set (match_operand:SI 0 "register_operand" "=x")
(lt:SI (xor:SI (match_operand:SI 1 "reg_or_mem_operand" "rm")
(const_int SIGNBIT))
(match_operand:SI 2 "const_int_operand" "")))]
""
{
HOST_WIDE_INT sign = (HOST_WIDE_INT)1 << 35;
operands[2] = gen_int_mode (INTVAL (operands[2]) ^ sign, SImode);
if (INTVAL (operands[2]) & ~(HOST_WIDE_INT)0777777)
return "skipl %0,%1\;%_caml %0,[%2]\;%_%_tdza %0,%0\;%_%_%_movei %0,1";
else
return "skipl %0,%1\;%_cail %0,%2\;%_%_tdza %0,%0\;%_%_%_movei %0,1";
}
[(set_attr "length" "4")])
(define_insn "*sltu_plus"
[(set (match_operand:SI 0 "register_operand" "=x")
(lt:SI (xor:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "const_int_operand" ""))
(const_int SIGNBIT))
(match_operand:SI 3 "const_int_operand" "")))]
""
{
HOST_WIDE_INT sign = (HOST_WIDE_INT)1 << 35;
operands[2] = gen_int_mode (-INTVAL (operands[2]), SImode);
if (INTVAL (operands[2]) & ~(HOST_WIDE_INT)0777777)
output_asm_insn ("caml %1,[%2]", operands);
else
output_asm_insn ("cail %1,%2", operands);
operands[3] = gen_int_mode ((INTVAL (operands[3]) ^ sign)
- INTVAL (operands[2]), SImode);
if (INTVAL (operands[3]) & ~(HOST_WIDE_INT)0777777)
output_asm_insn ("%_caml %1,[%3]", operands);
else
output_asm_insn ("%_cail %1,%3", operands);
return "%_%_tdza %0,%0\;%_%_%_movei %0,1";
}
[(set_attr "length" "4")])
(define_insn "*cbranchltu"
[(set (pc)
(if_then_else
(lt (xor:SI (match_operand:SI 0 "register_operand" "r")
(const_int SIGNBIT))
(match_operand:SI 1 "const_int_operand" ""))
(label_ref (match_operand 2 "" ""))
(pc)))]
""
{
rtx ops[5];
ops[0] = operands[0];
ops[1] = operands[0];
ops[2] = GEN_INT (0);
ops[3] = operands[1];
ops[4] = operands[2];
return pdp10_output_range_compare (insn, ops, 1);
}
[(set_attr "length" "4")])
(define_insn "*cbranchltu_mem"
[(set (pc)
(if_then_else
(lt (xor:SI (match_operand:SI 0 "memory_operand" "m")
(const_int SIGNBIT))
(match_operand:SI 1 "const_int_operand" ""))
(label_ref (match_operand 2 "" ""))
(pc)))
(clobber (match_scratch:SI 3 "=x"))]
""
{
rtx ops[5];
ops[0] = operands[3];
ops[1] = operands[0];
ops[2] = GEN_INT (0);
ops[3] = operands[1];
ops[4] = operands[2];
return pdp10_output_range_compare (insn, ops, 1);
}
[(set_attr "length" "4")])
(define_insn "*cbranchltu_plus"
[(set (pc)
(if_then_else
(lt (xor:SI (plus:SI (match_operand:SI 0 "reg_or_mem_operand" "r")
(match_operand:SI 1 "const_int_operand" ""))
(const_int SIGNBIT))
(match_operand:SI 2 "const_int_operand" ""))
(label_ref (match_operand 3 "" ""))
(pc)))]
""
{
rtx ops[5];
ops[0] = operands[0];
ops[1] = operands[0];
ops[2] = operands[1];
ops[3] = operands[2];
ops[4] = operands[3];
return pdp10_output_range_compare (insn, ops, 1);
}
[(set_attr "length" "4")])
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(lshiftrt:SI (match_operand:SI 1 "memory_operand" "m")
(match_operand:SI 2 "const_int_operand" "i")))]
"INTVAL (operands[2]) != 4 && INTVAL (operands[2]) != 18
&& INTVAL (operands[2]) != 20"
{
rtx ops[4];
ops[0] = operands[0];
ops[1] = operands[1];
ops[2] = GEN_INT (BITS_PER_WORD - INTVAL (operands[2]));
ops[3] = GEN_INT (0);
if (get_attr_length (insn) == 1)
output_asm_insn (pdp10_output_extzv (insn, ops), ops);
else
output_asm_insn (pdp10_output_extzv_sequence (ops), ops);
return "";
}
[(set (attr "length")
(if_then_else
(and (ne (symbol_ref "TARGET_LARGE") (const_int 0))
(match_operand:SI 1 "pdp10_constaddr_memory_operand" ""))
(const_int 1)
(const_int 2)))])
(define_insn ""
[(set (match_operand:SI 0 "memory_operand" "=m")
(and:SI (match_operand:SI 1 "memory_operand" "0")
(const_int LEFT_HALF)))]
""
"hllzs %W0")
(define_insn ""
[(set (match_operand:HI 0 "memory_operand" "=m")
(const_int 0))]
"MEM_ALIGN (operands[0]) == 36"
"hrrzs %W0")
(define_insn ""
[(set (match_operand:SI 0 "reg_or_mem_operand" "+rm")
(and:SI (match_dup 0) (const_int RIGHT_HALF)))
(set (match_operand:SI 1 "register_operand" "=x")
(and:SI (match_operand:SI 2 "reg_or_mem_operand" "=0")
(const_int RIGHT_HALF)))]
""
"hrrzs %1,%0")
(define_insn ""
[(set (match_operand:SI 0 "reg_or_mem_operand" "+rm")
(and:SI (match_dup 0) (const_int LEFT_HALF)))
(set (match_operand:SI 1 "register_operand" "=x")
(and:SI (match_operand:SI 2 "reg_or_mem_operand" "=0")
(const_int LEFT_HALF)))]
""
"hllzs %1,%0")
(define_insn ""
[(set (match_operand:SI 0 "reg_or_mem_operand" "+rm")
(ashift:SI (match_dup 0) (const_int 18)))
(set (match_operand:SI 1 "register_operand" "=x")
(ashift:SI (match_operand:SI 2 "reg_or_mem_operand" "=0")
(const_int 18)))]
""
"hrlzs %1,%0")
(define_insn ""
[(set (match_operand:SI 0 "reg_or_mem_operand" "+rm")
(lshiftrt:SI (match_dup 0) (const_int 18)))
(set (match_operand:SI 1 "register_operand" "=x")
(lshiftrt:SI (match_operand:SI 2 "reg_or_mem_operand" "=0")
(const_int 18)))]
""
"hlrzs %1,%0")
(define_insn ""
[(set (match_operand:SI 0 "reg_or_mem_operand" "+rm")
(ior:SI (match_dup 0) (const_int LEFT_HALF)))
(set (match_operand:SI 1 "register_operand" "=x")
(ior:SI (match_operand:SI 2 "reg_or_mem_operand" "=0")
(const_int LEFT_HALF)))]
""
"hrros %1,%0")
(define_insn ""
[(set (match_operand:SI 0 "reg_or_mem_operand" "+rm")
(ior:SI (match_dup 0) (const_int RIGHT_HALF)))
(set (match_operand:SI 1 "register_operand" "=x")
(ior:SI (match_operand:SI 2 "reg_or_mem_operand" "=0")
(const_int RIGHT_HALF)))]
""
"hllos %1,%0")
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(ior:SI (ashift:SI (match_operand:SI 1 "reg_or_mem_operand" "rm")
(const_int 18))
(const_int RIGHT_HALF)))]
""
"hrlo %0,%1")
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(ior:SI (lshiftrt:SI (match_operand:SI 1 "reg_or_mem_operand" "rm")
(const_int 18))
(const_int LEFT_HALF)))]
""
"hlro %0,%1")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Data Movement
(define_expand "movqi"
[(set (match_operand:QI 0 "reg_or_mem_operand" "")
(match_operand:QI 1 "general_operand" ""))]
""
"if (no_new_pseudos)
{
if (REG_P (operands[0]) && GET_CODE (operands[1]) == CONST_INT)
operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
}
else
{
if (GET_CODE (operands[0]) == SUBREG
&& GET_CODE (SUBREG_REG (operands[0])) == ZERO_EXTRACT)
{
if (GET_CODE (XEXP (SUBREG_REG (operands[0]), 0)) == MEM
&& SUBREG_BYTE (operands[0]) == 3
&& GET_CODE (XEXP (SUBREG_REG (operands[0]), 1)) == CONST_INT
&& INTVAL (XEXP (SUBREG_REG (operands[0]), 1)) == 9
&& GET_CODE (XEXP (SUBREG_REG (operands[0]), 2)) == CONST_INT
&& INTVAL (XEXP (SUBREG_REG (operands[0]), 2)) == 27
&& MEM_SCALAR_P (XEXP (SUBREG_REG (operands[0]), 0)))
emit_move_insn (XEXP (SUBREG_REG (operands[0]), 0),
convert_to_mode (SImode, operands[1], 1));
else
emit_move_insn (SUBREG_REG (operands[0]),
convert_to_mode (SImode, operands[1], 1));
DONE;
}
else if (GET_CODE (operands[1]) == SUBREG
&& GET_CODE (SUBREG_REG (operands[1])) == ZERO_EXTRACT)
{
rtx temp = gen_reg_rtx (SImode);
emit_move_insn (temp, SUBREG_REG (operands[1]));
operands[1] = gen_rtx_SUBREG (QImode, temp, 3);
}
else if (GET_CODE (operands[1]) == CONST_INT)
{
rtx temp = gen_reg_rtx (SImode);
emit_insn (gen_movsi (temp, operands[1]));
operands[1] = gen_rtx_SUBREG (QImode, temp, 3);
}
if (GET_CODE (operands[0]) == MEM)
operands[1] = force_reg (QImode, operands[1]);
}")
(define_insn "*movqi_reg"
[(set (match_operand:QI 0 "register_operand" "=r")
(match_operand:QI 1 "register_operand" "r"))]
""
"move %0,%1")
(define_insn "*LDBzqi_sequence"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(zero_extend:SI (match_operand:QI 1 "memory_operand" "m,>")))]
"TARGET_EXTENDED
&& !CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
&& pdp10_pointer_alignment (XEXP (operands[1], 0)) >= UNITS_PER_WORD
&& (GET_CODE (XEXP (operands[1], 0)) == REG
|| (INTVAL (XEXP (XEXP (operands[1], 0), 1)) % UNITS_PER_WORD == 0))"
{
rtx ops[4];
ops[0] = operands[0];
ops[1] = operands[1];
ops[2] = GEN_INT (9);
ops[3] = GEN_INT (0);
output_asm_insn (pdp10_output_extzv_sequence (ops), ops);
return "";
}
[(set_attr "length" "2")])
(define_insn "*LDBzqi"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(zero_extend:SI (match_operand:QI 1 "memory_operand" ">,m")))]
""
"*return pdp10_output_load_unsigned_byte (insn, operands);"
[(set_attr "reorg_type" "none,ldb")])
(define_insn "*LDBIzqi"
[(set (match_operand:SI 0 "register_operand" "=r")
(zero_extend:SI (match_operand:QI 1 "memory_operand" "<")))]
"TARGET_XKL2"
"*return pdp10_output_load_unsigned_byte (insn, operands);")
(define_insn "*LDBEqi"
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
(sign_extend:SI (match_operand:QI 1 "memory_operand" ">,<,m")))]
"TARGET_XKL2"
"*return pdp10_output_load_signed_byte (insn, operands);"
[(set_attr "reorg_type" "none,none,ldb")])
(define_insn "*LDBEqi_sequence"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(sign_extend:SI (match_operand:QI 1 "memory_operand" ">,m")))]
"!TARGET_XKL2"
{
if (/*CONSTANT_ADDRESS_P (XEXP (operands[1], 0)) || */
pdp10_pointer_alignment (XEXP (operands[1], 0)) >= UNITS_PER_WORD)
{
rtx ops[4];
int offset = pdp10_pointer_offset (XEXP (operands[1], 0));
ops[0] = operands[0];
ops[1] = operands[1];
ops[2] = GEN_INT (9);
ops[3] = GEN_INT (0);
output_asm_insn (pdp10_output_extv_sequence (ops), ops);
return "";
}
else
{
if (which_alternative == 0)
return "ildb %0,%1\;trne %0,400\;%_orcmi %0,777";
else
return "ldb %0,%1\;trne %0,400\;%_orcmi %0,777";
}
}
[(set_attr "length" "3")
(set_attr "reorg_type" "none,ldb")])
(define_insn "*LDBqi"
[(set (match_operand:QI 0 "register_operand" "=r,r")
(match_operand:QI 1 "memory_operand" ">,m"))]
""
"*return pdp10_output_load_unsigned_byte (insn, operands);"
[(set_attr "reorg_type" "none,ldb")])
; "@
; ildb %0,%1
; ldb %0,%1")
(define_insn "*LDBIqi"
[(set (match_operand:QI 0 "register_operand" "=r")
(match_operand:QI 1 "memory_operand" "<"))]
"TARGET_XKL2"
"*return pdp10_output_load_unsigned_byte (insn, operands);")
(define_insn "*DPBqi"
[(set (match_operand:QI 0 "memory_operand" "=>,m")
(match_operand:QI 1 "register_operand" "r,r"))]
""
"*return pdp10_output_store_byte (insn, operands);"
[(set_attr "reorg_type" "none,dpb")])
(define_insn "*DPBIqi"
[(set (match_operand:QI 0 "memory_operand" "=<")
(match_operand:QI 1 "register_operand" "r"))]
"TARGET_XKL2"
"*return pdp10_output_store_byte (insn, operands);")
(define_expand "movhi"
[(set (match_operand:HI 0 "reg_or_mem_operand" "")
(match_operand:HI 1 "general_operand" ""))]
""
"if (no_new_pseudos)
{
if (REG_P (operands[0]) && GET_CODE (operands[1]) == CONST_INT)
operands[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
}
else
{
if (GET_CODE (operands[0]) == SUBREG
&& GET_CODE (SUBREG_REG (operands[0])) == ZERO_EXTRACT)
{
if (GET_CODE (XEXP (SUBREG_REG (operands[0]), 0)) == MEM
&& SUBREG_BYTE (operands[0]) == 2
&& GET_CODE (XEXP (SUBREG_REG (operands[0]), 1)) == CONST_INT
&& INTVAL (XEXP (SUBREG_REG (operands[0]), 1)) == 18
&& GET_CODE (XEXP (SUBREG_REG (operands[0]), 2)) == CONST_INT
&& INTVAL (XEXP (SUBREG_REG (operands[0]), 2)) == 18
&& MEM_SCALAR_P (XEXP (SUBREG_REG (operands[0]), 0)))
emit_move_insn (XEXP (SUBREG_REG (operands[0]), 0),
convert_to_mode (SImode, operands[1], 1));
else
emit_move_insn (SUBREG_REG (operands[0]),
convert_to_mode (SImode, operands[1], 1));
DONE;
}
else if (GET_CODE (operands[1]) == SUBREG
&& GET_CODE (SUBREG_REG (operands[1])) == ZERO_EXTRACT)
{
rtx temp = gen_reg_rtx (SImode);
emit_move_insn (temp, XEXP (operands[1], 0));
operands[1] = gen_rtx_SUBREG (HImode, temp, 2);
}
else if (GET_CODE (operands[1]) == CONST_INT)
{
rtx reg = gen_reg_rtx (SImode);
emit_insn (gen_movsi (reg, operands[1]));
operands[1] = gen_rtx_SUBREG (HImode, reg, 2);
}
if (GET_CODE (operands[0]) == MEM)
operands[1] = force_reg (HImode, operands[1]);
}")
(define_insn "*movhi"
[(set (match_operand:HI 0 "register_operand" "=r")
(match_operand:HI 1 "register_operand" "r"))]
""
"move %0,%1")
; (define_insn "*halfword_move"
; [(set (match_operand:SI 0 "pdp10_halfword_destination" "=")
; (match_operand:SI 1 "pdp10_halfword_source" ""))]
; ""
; "*pdp10_output_halfword_move (operands);")
(define_insn "*HLR"
[(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
(const_int 18)
(const_int 18))
(subreg:SI (match_operand:HI 1 "memory_operand" "m") 0))]
""
"hlr %0,%W1")
(define_insn "*HLL"
[(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
(const_int 18)
(const_int 0))
(subreg:SI (match_operand:HI 1 "memory_operand" "m") 0))]
""
"hll %0,%W1")
(define_insn "*HLLM"
[(set (mem:SI (match_operand:SI 0 "address_operand" "p"))
(ior:SI (and:SI (match_operand:SI 1 "register_operand" "r")
(const_int LEFT_HALF))
(zero_extend:SI (mem:HI (match_dup 0)))))]
""
{
if (GET_CODE (operands[0]) == CONST
&& TARGET_EXTENDED && !TARGET_SMALLISH)
/* ADDRESS: ... */
return "hllm %1,@[%W0]";
else
return "hllm %1,%W0";
})
(define_insn "HRR"
[(set (zero_extract:SI (match_operand:SI 0 "reg_or_mem_operand" "+r,m")
(const_int 18)
(const_int 18))
(and:SI (match_operand:SI 1 "reg_or_mem_operand" "rm,r")
(const_int RIGHT_HALF)))]
""
"@
hrr %0,%1
hrrm %1,%0")
(define_insn "*HRL"
[(set (zero_extract:SI (match_operand:SI 0 "reg_or_mem_operand" "+r,m")
(const_int 18)
(const_int 0))
(and:SI (match_operand:SI 1 "reg_or_mem_operand" "rm,r")
(const_int RIGHT_HALF)))]
""
"@
hrl %0,%1
hrlm %1,%0")
; (define_insn "*HxR"
; [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
; (const_int 18)
; (const_int 18))
; (subreg:SI (match_operand:HI 1 "memory_operand" "m") 0))]
; ""
; "*return pdp10_output_halfword_insv (insn, operands, 18);")
(define_insn "*HxRM"
[(set (subreg:SI (match_operand:HI 1 "memory_operand" "=m") 0)
(zero_extract:SI (match_operand:SI 0 "register_operand" "r")
(const_int 18)
(const_int 18)))]
""
"*return pdp10_output_halfword_extv (insn, operands, 18);")
; (define_insn "*HxL"
; [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
; (const_int 18)
; (const_int 0))
; (subreg:SI (match_operand:HI 1 "memory_operand" "m") 0))]
; ""
; "*return pdp10_output_halfword_insv (insn, operands, 0);")
(define_insn "*HxLM"
[(set (match_operand:HI 1 "memory_operand" "=m")
(subreg:HI (lshiftrt:SI (match_operand:SI 0 "register_operand" "r")
(const_int 18)) 2))]
""
"*return pdp10_output_halfword_extv (insn, operands, 0);")
(define_insn "*HLR"
[(set (zero_extract:SI (match_operand:SI 0 "reg_or_mem_operand" "+r,m")
(const_int 18)
(const_int 18))
(lshiftrt:SI (match_operand:SI 1 "reg_or_mem_operand" "rm,r")
(const_int 18)))]
""
"@
hlr %0,%W1
hlrm %1,%W0")
(define_insn "HRRZ"
[(set (match_operand:SI 0 "reg_or_mem_operand" "=r,m")
(and:SI (match_operand:SI 1 "reg_or_mem_operand" "rm,r")
(const_int RIGHT_HALF)))]
""
{
if (REG_P (operands[0]) && REG_P (operands[1])
&& REGNO (operands[0]) == REGNO (operands[1])
&& zero_extended_p (operands[0], 18, insn))
return "";
else
{
const char *insn[] = { "hrrz %0,%W1", "hrrzm %1,%W0" };
return insn[which_alternative];
}
})
(define_insn "*HRRO"
[(set (match_operand:SI 0 "reg_or_mem_operand" "=r,m")
(ior:SI (match_operand:SI 1 "reg_or_mem_operand" "rm,r")
(const_int LEFT_HALF)))]
""
"@
hrro %0,%W1
hrrom %1,%W0")
(define_insn "*HLLZ"
[(set (match_operand:SI 0 "reg_or_mem_operand" "=r,m")
(and:SI (match_operand:SI 1 "reg_or_mem_operand" "rm,r")
(const_int LEFT_HALF)))]
""
"@
hllz %0,%W1
hllzm %1,%W0")
(define_insn "*HLLO"
[(set (match_operand:SI 0 "reg_or_mem_operand" "=r,m")
(ior:SI (match_operand:SI 1 "reg_or_mem_operand" "rm,r")
(const_int RIGHT_HALF)))]
""
"@
hllo %0,%W1
hllom %1,%W0")
(define_insn "*HLL"
[(set (zero_extract:SI (match_operand:SI 0 "reg_or_mem_operand" "+r,m")
(const_int 18)
(const_int 0))
(lshiftrt:SI (match_operand:SI 1 "reg_or_mem_operand" "rm,r")
(const_int 18)))]
""
"@
hll %0,%W1
hllm %1,%W0")
(define_insn "HLRZ"
[(set (match_operand:SI 0 "reg_or_mem_operand" "=r,m")
(lshiftrt:SI (match_operand:SI 1 "reg_or_mem_operand" "rm,r")
(const_int 18)))]
""
"@
hlrz %0,%1
hlrzm %1,%0")
(define_insn "HLRE"
[(set (match_operand:SI 0 "reg_or_mem_operand" "=r,m")
(ashiftrt:SI (match_operand:SI 1 "reg_or_mem_operand" "rm,r")
(const_int 18)))]
""
"@
hlre %0,%1
hlrem %1,%0")
(define_insn "*HLRE_extract"
[(set (match_operand:SI 0 "register_operand" "=r")
(sign_extract:SI (match_operand:HI 1 "memory_operand" "m")
(const_int 18)
(const_int 0)))]
""
"hlre %0,%W1")
(define_insn "*HRLZ"
[(set (match_operand:SI 0 "reg_or_mem_operand" "=r,m")
(ashift:SI (match_operand:SI 1 "reg_or_mem_operand" "rm,r")
(const_int 18)))]
""
"@
hrlz %0,%1
hrlzm %1,%0")
(define_insn "*loadhi"
[(set (match_operand:HI 0 "register_operand" "=r")
(match_operand:HI 1 "memory_operand" "m>"))]
""
"*return pdp10_output_movhi (operands, 0);")
(define_insn "*zloadhi"
[(set (match_operand:SI 0 "register_operand" "=r")
(zero_extend:SI (match_operand:HI 1 "memory_operand" "m>")))]
""
"*return pdp10_output_movhi (operands, 0);")
(define_insn "*sloadhi_1"
[(set (match_operand:SI 0 "register_operand" "=r")
(sign_extend:SI
(match_operand:HI 1 "pdp10_maybe_volatile_memory_operand" "m")))]
"pdp10_pointer_alignment (XEXP (operands[1], 0)) >= UNITS_PER_WORD"
"*return pdp10_output_movhi (operands, 1);")
(define_insn "*sloadhi_2"
[(set (match_operand:SI 0 "register_operand" "=r")
(sign_extend:SI
(match_operand:HI 1 "pdp10_maybe_volatile_memory_operand" "m")))]
"pdp10_pointer_alignment (XEXP (operands[1], 0)) < UNITS_PER_WORD"
{
output_asm_insn (pdp10_output_movhi (operands, 0), operands);
return "hrre %0,%0";
}
[(set_attr "length" "2")])
(define_insn "storehi"
[(set (match_operand:HI 0 "memory_operand" "=m>")
(match_operand:HI 1 "register_operand" "r"))]
""
"*return pdp10_output_movhi (operands, 0);")
(define_insn "*zstorehi"
[(set (match_operand:SI 0 "memory_operand" "=m")
(zero_extend:SI (match_operand:HI 1 "register_operand" "r")))]
""
"hrrzm %1,%0")
(define_insn "*sstorehi"
[(set (match_operand:SI 0 "memory_operand" "=m")
(sign_extend:SI (match_operand:HI 1 "memory_operand" "r")))]
""
"hrrem %1,%0")
(define_expand "extv"
[(set (match_operand:SI 0 "register_operand" "")
(sign_extract:SI (match_operand:SI 1 "reg_or_mem_operand" "")
(match_operand:SI 2 "const_int_operand" "")
(match_operand:SI 3 "const_int_operand" "")))]
""
"if (INTVAL (operands[2]) + INTVAL (operands[3]) > BITS_PER_WORD)
FAIL;
if (!TARGET_XKL2)
{
if (pdp10_expand_extv (operands))
DONE;
}")
(define_insn "*extv_reg"
[(set (match_operand:SI 0 "register_operand" "=r")
(sign_extract:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "const_int_operand" "")
(match_operand:SI 3 "const_int_operand" "")))]
"!TARGET_XKL2"
"*return pdp10_output_extv_sequence (operands);"
[(set_attr "length" "3")])
(define_insn "*extv_mem"
[(set (match_operand:SI 0 "register_operand" "=r")
(sign_extract:SI (match_operand:QI 1 "memory_operand" "m")
(match_operand:SI 2 "const_int_operand" "")
(match_operand:SI 3 "const_int_operand" "")))]
"!TARGET_XKL2"
"*return pdp10_output_extv_sequence (operands);"
[(set_attr "length" "3")])
(define_insn "*extv_memsi"
[(set (match_operand:SI 0 "register_operand" "=r")
(sign_extract:SI (match_operand:SI 1 "memory_operand" "m")
(match_operand:SI 2 "const_int_operand" "")
(match_operand:SI 3 "const_int_operand" "")))]
"!TARGET_XKL2"
"*return pdp10_output_extv_sequence (operands);"
[(set_attr "length" "3")])
(define_insn "*LDBE_reg"
[(set (match_operand:SI 0 "register_operand" "=r")
(sign_extract:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "const_int_operand" "")
(match_operand:SI 3 "const_int_operand" "")))]
"TARGET_XKL2"
"*return pdp10_output_extv (insn, operands);")
(define_insn "*LDBE_regqi"
[(set (match_operand:SI 0 "register_operand" "=r")
(sign_extract:SI (match_operand:QI 1 "register_operand" "r")
(match_operand:SI 2 "const_int_operand" "")
(match_operand:SI 3 "const_int_operand" "")))]
"TARGET_XKL2"
"*return pdp10_output_extv (insn, operands);")
(define_insn "*LDBE_mem"
[(set (match_operand:SI 0 "register_operand" "=r")
(sign_extract:SI (match_operand:QI 1 "memory_operand" "r")
(match_operand:SI 2 "const_int_operand" "")
(match_operand:SI 3 "const_int_operand" "")))]
"TARGET_XKL2"
"*return pdp10_output_extv (insn, operands);")
(define_expand "extzv"
[(set (match_operand:SI 0 "register_operand" "")
(zero_extract:SI (match_operand:SI 1 "reg_or_mem_operand" "")
(match_operand:SI 2 "const_int_operand" "")
(match_operand:SI 3 "const_int_operand" "")))]
""
"if (INTVAL (operands[2]) + INTVAL (operands[3]) > BITS_PER_WORD)
FAIL;
if (pdp10_expand_extzv (operands))
DONE;")
(define_insn "*extzv_reg_sequence"
[(set (match_operand:SI 0 "register_operand" "=r")
(zero_extract:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "const_int_operand" "")
(match_operand:SI 3 "const_int_operand" "")))]
"INTVAL (operands[2]) == 16 || INTVAL (operands[3]) == 0"
"*return pdp10_output_extzv_sequence (operands);"
[(set_attr "length" "3")])
(define_insn "*extzv_memsi_sequence"
[(set (match_operand:SI 0 "register_operand" "=r")
(zero_extract:SI (match_operand:SI 1 "memory_operand" "m")
(match_operand:SI 2 "const_int_operand" "")
(match_operand:SI 3 "const_int_operand" "")))]
"INTVAL (operands[2]) == 16
|| (TARGET_EXTENDED
&& (INTVAL (operands[3]) == 0
|| INTVAL (operands[2]) + INTVAL (operands[3]) == 36)
&& !CONSTANT_ADDRESS_P (XEXP (operands[1], 0)))"
; && (GET_CODE (XEXP (operands[1], 0)) == REG
; || GET_CODE (XEXP (operands[1], 0)) == PLUS))"
; || (GET_CODE (XEXP (operands[1], 0)) == PLUS
; && INTVAL (XEXP (XEXP (operands[1], 0), 1))
; % UNITS_PER_WORD == 0)))"
"*return pdp10_output_extzv_sequence (operands);"
[(set_attr "length" "3")])
(define_insn "*extzv_mem_sequence"
[(set (match_operand:SI 0 "register_operand" "=r")
(zero_extract:SI (match_operand:QI 1 "memory_operand" "m")
(match_operand:SI 2 "const_int_operand" "")
(match_operand:SI 3 "const_int_operand" "")))]
"INTVAL (operands[2]) == 16
|| (TARGET_EXTENDED
&& INTVAL (operands[3]) == 0
&& !CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
&& (GET_CODE (XEXP (operands[1], 0)) == REG
|| (GET_CODE (XEXP (operands[1], 0)) == PLUS
&& INTVAL (XEXP (XEXP (operands[1], 0), 1))
% UNITS_PER_WORD == 0)))"
"*return pdp10_output_extzv_sequence (operands);"
[(set_attr "length" "3")])
(define_insn "*extzv_reg"
[(set (match_operand:SI 0 "register_operand" "=r")
(zero_extract:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "const_int_operand" "")
(match_operand:SI 3 "const_int_operand" "")))]
"INTVAL (operands[2]) != 16"
"*return pdp10_output_extzv (insn, operands);")
(define_insn "*extzv_mem"
[(set (match_operand:SI 0 "register_operand" "=r")
(zero_extract:SI (match_operand:QI 1 "memory_operand" "m")
(match_operand:SI 2 "const_int_operand" "")
(match_operand:SI 3 "const_int_operand" "")))]
"INTVAL (operands[2]) != 16"
"*return pdp10_output_extzv (insn, operands);")
(define_insn "*extzv_memsi"
[(set (match_operand:SI 0 "register_operand" "=r")
(zero_extract:SI (match_operand:SI 1 "memory_operand" "m")
(match_operand:SI 2 "const_int_operand" "")
(match_operand:SI 3 "const_int_operand" "")))]
"INTVAL (operands[2]) != 16"
"*return pdp10_output_extzv (insn, operands);")
(define_insn "*move_dpb"
[(set (match_operand:QI 0 "memory_operand" "=m")
(subreg:QI (zero_extract:SI (match_operand:SI 2 "memory_operand" "m")
(const_int 9)
(const_int 27)) 3))
(clobber (match_scratch:SI 1 "=r"))]
""
{
output_asm_insn ("move %1,%2", operands);
return pdp10_output_store_byte (insn, operands);
}
[(set_attr "length" "2")])
(define_insn "*move_dpb2"
[(set (zero_extract:SI (match_operand:SI 0 "memory_operand" "+m")
(const_int 8)
(const_int 0))
(and:SI (match_operand:SI 2 "memory_operand" "m")
(const_int 255)))
(clobber (match_scratch:SI 1 "=r"))]
""
{
output_asm_insn ("move %1,%2", operands);
return pdp10_output_store_byte (insn, operands);
}
[(set_attr "length" "2")])
(define_expand "insv"
[(set (zero_extract:SI (match_operand:SI 0 "reg_or_mem_operand" "")
(match_operand:SI 1 "const_int_operand" "")
(match_operand:SI 2 "const_int_operand" ""))
(match_operand:SI 3 "register_operand" ""))]
""
"if (INTVAL (operands[1]) + INTVAL (operands[2]) > BITS_PER_WORD)
FAIL;
/* FIXME: is this necessary? According to test/misc/array-loop.c, yes. */
if (GET_CODE (operands[0]) == MEM
&& GET_CODE (XEXP (operands[0], 0)) == REG
&& INTVAL (operands[1]) == BITS_PER_WORD
&& INTVAL (operands[2]) == 0)
{
emit_move_insn (gen_rtx_MEM (SImode, XEXP (operands[0], 0)),
operands[3]);
DONE;
}")
; (define_insn ""
; [(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
; (const_int 18)
; (const_int 18))
; (match_operand:SI 3 "register_operand" "r"))]
; ""
; "*return pdp10_output_insv (insn, operands);")
(define_insn "*insv_reg"
[(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r")
(match_operand:SI 1 "const_int_operand" "")
(match_operand:SI 2 "const_int_operand" ""))
(match_operand:SI 3 "register_operand" "r"))]
""
"*return pdp10_output_insv (insn, operands);")
(define_insn "*insv_mem"
[(set (zero_extract:SI (match_operand:QI 0 "memory_operand" "+m")
(match_operand:SI 1 "const_int_operand" "")
(match_operand:SI 2 "const_int_operand" ""))
(match_operand:SI 3 "register_operand" "r"))]
""
"*return pdp10_output_insv (insn, operands);")
(define_insn "*insv_memsi"
[(set (zero_extract:SI (match_operand:SI 0 "memory_operand" "+m")
(match_operand:SI 1 "const_int_operand" "")
(match_operand:SI 2 "const_int_operand" ""))
(match_operand:SI 3 "register_operand" "r"))]
""
"*return pdp10_output_insv (insn, operands);")
(define_expand "movsi"
[(set (match_operand:SI 0 "reg_or_mem_operand" "")
(match_operand:SI 1 "general_operand" ""))]
""
"if (GET_CODE (operands[0]) == ZERO_EXTRACT)
operands[1] = force_reg (SImode, operands[1]);")
;; Special version using SKIPA to load a full-word constant. This may
;; be beneficial on processors with a cache. Note the 'x' constraint
;; on alternative 7. Reload can fall back on the last alternative if
;; instisting on moving to register 0.
(define_insn "*movsi_cache"
[(set (match_operand:SI 0 "reg_or_mem_operand" "=r,r,r,r,r,r,r,x,m,m,m,r")
;; ADDRESS: the S constraint allows a symbol.
(match_operand:SI 1 "general_operand" "rm,I,S,L,M,N,P,i,O,M,r,i"))]
"TARGET_CACHE && !optimize_size"
"*return pdp10_output_movsi (insn, which_alternative);"
[(set_attr "length" "1,1,1,1,1,1,1,2,1,1,1,1")])
(define_insn "*movsi_nocache"
[(set (match_operand:SI 0 "reg_or_mem_operand" "=r,r,r,r,r,r,r,r,m,m,m")
;; ADDRESS: the S constraint allows a symbol.
(match_operand:SI 1 "general_operand" "rm,I,S,L,M,N,P,i,O,M,r"))]
""
"*return pdp10_output_movsi (insn, which_alternative);")
(define_insn "move_two_halves"
[(set (match_operand:SI 0 "register_operand" "=r")
(ior:SI (ashift:SI (match_operand:SI 1 "immediate_operand" "p")
(const_int 18))
(match_operand:SI 2 "immediate_operand" "p")))]
""
"move %0,[%1,,%2]")
(define_insn "*MOVEI_const_plus_reg"
[(set (match_operand:SI 0 "register_operand" "=r")
(and:SI (plus:SI (match_operand:SI 1 "register_operand" "x")
(match_operand:SI 2 "const_int_operand" "I"))
(const_int RIGHT_HALF)))]
"pdp10_const_ok_for_letter_p (INTVAL (operands[2]), 'I')"
"movei %0,%2(%1)")
(define_insn "*MOVS"
[(set (match_operand:SI 0 "reg_or_mem_operand" "=r,m")
(match_operator:SI 1 "pdp10_rotate_operator"
[(match_operand:SI 2 "reg_or_mem_operand" "rm,r") (const_int 18)]))]
""
"@
movs %0,%2
movsm %2,%0")
(define_insn "*EXCH"
[(set (match_operand:SI 0 "reg_or_mem_operand" "+rm")
(match_operand:SI 1 "register_operand" "r"))
(set (match_operand:SI 2 "register_operand" "=1")
(match_dup 0))]
""
"exch %1,%0")
(define_insn "*SETZB"
[(set (match_operand:SI 0 "reg_or_mem_operand" "=rm") (const_int 0))
(set (match_operand:SI 1 "register_operand" "=r") (const_int 0))]
""
"setzb %1,%0")
(define_expand "movdi"
[(set (match_operand:DI 0 "reg_or_mem_operand" "")
(match_operand:DI 1 "general_operand" ""))]
""
"if (!HAVE_DMOVE && pdp10_expand_dmove (operands[0], operands[1]))
DONE;")
;; TODO: if there's a REG_UNUSED note attached to this insn, avoid
;; moving the unused part of the DImode register.
(define_insn "DMOVE"
[(set (match_operand:DI 0 "reg_or_mem_operand" "=r,r,r,r,r,o,m")
(match_operand:DI 1 "general_operand" "rm,O,I,J,i,O,r"))]
"TARGET_KI10up"
"@
dmove %0,%1
setzb %0,%Z0
movei %0,0\;movei %Z0,%1
seto %0,\;movni %Z0,%n1
dmove %0,[%D1]
setzm %0\;setzm %Z0
dmovem %1,%0"
[(set_attr "length" "1,1,2,2,1,2,1")])
(define_insn "*movdi"
[(set (match_operand:DI 0 "reg_or_mem_operand" "=r,r,r,r,r,o,o")
(match_operand:DI 1 "general_operand" "ro,O,I,J,i,O,r"))]
"!TARGET_KI10up"
"@
move %0,%1\;move %Z0,%Z1
setzb %0,%Z0
movei %0,0\;movei %Z0,%1
seto %0,\;movni %Z0,%n1
move %0,[%A1]\;move %Z0,[%B1]
setzm %0\;setzm %Z0
movem %1,%0\;movem %Z1,%Z0"
[(set_attr "length" "2,1,2,2,2,2,2")])
(define_expand "movti"
[(set (match_operand:TI 0 "reg_or_mem_operand" "")
(match_operand:TI 1 "general_operand" ""))]
"TARGET_KI10up"
"if (pdp10_expand_move_4 (operands[0], operands[1]))
DONE;")
(define_insn "movsf"
[(set (match_operand:SF 0 "reg_or_mem_operand" "=r,r,r,r,m,m")
(match_operand:SF 1 "general_operand" "rm,R,G,F,R,r"))]
""
"@
move %0,%1%; movsf
movei %0,0%; movsf
movsi %0,%G1%; movsf
move %0,[%1]%; movsf
setzm %0%; movsf
movem %1,%0%; movsf")
(define_expand "movdf"
[(set (match_operand:DF 0 "reg_or_mem_operand" "")
(match_operand:DF 1 "general_operand" ""))]
""
"if (!HAVE_DMOVE && pdp10_expand_dmove (operands[0], operands[1]))
DONE;")
(define_insn "*movdf_KI10up"
[(set (match_operand:DF 0 "reg_or_mem_operand" "=r,r,r,r,o,m")
(match_operand:DF 1 "general_operand" "rm,R,G,F,R,r"))]
"TARGET_KI10up"
"@
dmove %0,%1
setzb %0,%Z0%; movdf
movsi %0,%G1%; movdf\;movei %Z0,0%; movdf
dmove %0,[%1]
setzm %0%; movdf\;setzm %Z0%; movdf
dmovem %1,%0"
[(set_attr "length" "1,1,2,1,2,1")])
(define_insn "*movdf_notKI10up"
[(set (match_operand:DF 0 "reg_or_mem_operand" "=r,r,r,r,o,o")
(match_operand:DF 1 "general_operand" "ro,R,G,F,R,r"))]
"!TARGET_KI10up"
"@
move %0,%1%; movdf\;move %Z0,%Z1%; movdf
setzb %0,%Z0%; movdf
movsi %0,%G1%; movdf\;movei %Z0,0%; movdf
move %0,[%A1]%; movdf\;move %Z0,[%B1]%; movdf
setzm %0%; movdf\;setzm %Z0%; movdf
movem %1,%0%; movdf\;movem %Z1,%Z0%; movdf"
[(set_attr "length" "2,1,2,2,2,2")])
(define_expand "movstrsi"
[(match_operand:BLK 0 "general_operand" "")
(match_operand:BLK 1 "general_operand" "")
(match_operand:SI 2 "general_operand" "")
(match_operand:SI 3 "const_int_operand" "")]
""
"if (pdp10_expand_movstrsi (operands))
DONE;
FAIL;")
(define_expand "clrstrsi"
[(match_operand:BLK 0 "general_operand" "")
(match_operand:SI 1 "general_operand" "")
(match_operand:SI 2 "const_int_operand" "")]
""
"if (pdp10_expand_clrstrsi (operands))
DONE;
FAIL;")
; (define_expand "cmpstrsi"
; [(set (match_operand:SI 0 "register_operand" "")
; (compare:SI (match_operand:BLK 1 "general_operand" "")
; (match_operand:BLK 2 "general_operand" "")))
; (use (match_operand:SI 3 "general_operand" ""))
; (use (match_operand:SI 4 "const_int_operand" ""))]
; "TARGET_KL10up && TARGET_STRING"
; "if (pdp10_expand_cmpstrsi (operands))
; DONE;
; FAIL;")
(define_insn "BLT"
[(unspec_volatile:BLK
[(match_operand:SI 0 "register_operand" "r")] VUNSPEC_BLT)
(clobber (match_dup 0))
(use (match_operand:BLK 1 "memory_operand" "m"))]
""
"blt %0,%1")
(define_insn "XBLT"
[(unspec_volatile:BLK
[(match_operand:TI 0 "register_operand" "+r")] VUNSPEC_XBLT)
(clobber (match_dup 0))]
"TARGET_KL10up"
"extend %0,[xblt]")
; (define_insn "MOVSLJ"
; [(unspec_volatile:BLK [(match_operand:SI 0 "register_operand" "+r")]
; VUNSPEC_MOVSLJ)]
; "TARGET_KL10up && TARGET_STRING"
; "extend %0,[movslj]")
; (define_insn "MOVST"
; [(unspec_volatile:BLK [(match_operand:SI 0 "register_operand" "+r")]
; VUNSPEC_MOVST)]
; "TARGET_KL10up && TARGET_STRING"
; "extend %0,[movst]")
; (define_insn "CMPS"
; [(unspec_volatile:BLK [(match_operand:SI 0 "register_operand" "+r")]
; VUNSPEC_CMPS)]
; "TARGET_KL10up && TARGET_STRING"
; "extend %0,[cmps]")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Conditional Data Movement
;; (define_expand "cstoresi4" ...)
;; (define_expand "cstoresf4" ...)
(define_expand "seq"
[(set (match_operand:SI 0 "register_operand" "")
(eq:SI (match_dup 1) (match_dup 2)))]
""
"if (GET_MODE (pdp10_compare_op0) == DFmode)
FAIL;
operands[1] = pdp10_compare_op0;
operands[2] = pdp10_compare_op1;")
(define_expand "sne"
[(set (match_operand:SI 0 "register_operand" "")
(ne:SI (match_dup 1) (match_dup 2)))]
""
"if (GET_MODE (pdp10_compare_op0) == DFmode)
FAIL;
operands[1] = pdp10_compare_op0;
operands[2] = pdp10_compare_op1;")
(define_expand "slt"
[(set (match_operand:SI 0 "register_operand" "")
(lt:SI (match_dup 1) (match_dup 2)))]
""
"if (GET_MODE (pdp10_compare_op0) == DFmode)
FAIL;
operands[1] = pdp10_compare_op0;
operands[2] = pdp10_compare_op1;")
(define_expand "sgt"
[(set (match_operand:SI 0 "register_operand" "")
(gt:SI (match_dup 1) (match_dup 2)))]
""
"if (GET_MODE (pdp10_compare_op0) == DFmode)
FAIL;
operands[1] = pdp10_compare_op0;
operands[2] = pdp10_compare_op1;")
(define_expand "sle"
[(set (match_operand:SI 0 "register_operand" "")
(le:SI (match_dup 1) (match_dup 2)))]
""
"if (GET_MODE (pdp10_compare_op0) == DFmode)
FAIL;
operands[1] = pdp10_compare_op0;
operands[2] = pdp10_compare_op1;")
(define_expand "sge"
[(set (match_operand:SI 0 "register_operand" "")
(ge:SI (match_dup 1) (match_dup 2)))]
""
"if (GET_MODE (pdp10_compare_op0) == DFmode)
FAIL;
operands[1] = pdp10_compare_op0;
operands[2] = pdp10_compare_op1;")
(define_expand "sltu"
[(set (match_operand:SI 0 "register_operand" "")
(lt:SI (match_dup 1) (match_dup 2)))]
""
"operands[1] = pdp10_flip_sign_bit (pdp10_compare_op0);
operands[2] = pdp10_flip_sign_bit (pdp10_compare_op1);")
(define_expand "sgtu"
[(set (match_operand:SI 0 "register_operand" "")
(gt:SI (match_dup 1) (match_dup 2)))]
""
"operands[1] = pdp10_flip_sign_bit (pdp10_compare_op0);
operands[2] = pdp10_flip_sign_bit (pdp10_compare_op1);")
(define_expand "sleu"
[(set (match_operand:SI 0 "register_operand" "")
(le:SI (match_dup 1) (match_dup 2)))]
""
"operands[1] = pdp10_flip_sign_bit (pdp10_compare_op0);
operands[2] = pdp10_flip_sign_bit (pdp10_compare_op1);")
(define_expand "sgeu"
[(set (match_operand:SI 0 "register_operand" "")
(ge:SI (match_dup 1) (match_dup 2)))]
""
"operands[1] = pdp10_flip_sign_bit (pdp10_compare_op0);
operands[2] = pdp10_flip_sign_bit (pdp10_compare_op1);")
(define_insn "*snesi"
[(set (match_operand:SI 0 "register_operand" "=r,x")
(ne:SI (match_operand:SI 1 "reg_or_mem_operand" "0,rm")
(const_int 0)))]
""
"@
skipe %@%0\;%_movei %0,1
skipe %0,%1\;%_movei %0,1"
[(set_attr "length" "2")])
(define_insn "*sgesi"
[(set (match_operand:SI 0 "register_operand" "=r")
(ge:SI (match_operand:SI 1 "register_operand" "0")
(const_int 0)))]
""
"lsh %0,-43\;xori %0,1"
[(set_attr "length" "2")])
;; This seemingly useless instruction combination is needed to enable
;; the combination below.
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(xor:SI (plus:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "reg_or_mem_operand" "rm"))
(const_int SIGNBIT)))]
"0"
"add %0,%2\;tlc %0,400000")
;; Calculate the truth value of this particular unsigned comparison
;; with ADD and JCRY0.
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(gt:SI (xor:SI (match_operand:SI 1 "register_operand" "r")
(const_int SIGNBIT))
(xor:SI (plus:SI (match_operand:SI 2 "register_operand" "0")
(match_operand:SI 3 "reg_or_mem_operand" "1"))
(const_int SIGNBIT))))]
"0"
"jfcl 17,.+1\;add %0,%3\;jcry0 .+2\;%_tdza %0,%0\;movei %0,1")
(define_insn "*sccsi"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(match_operator:SI 1 "pdp10_comparison_operator"
[(match_operand:SI 2 "reg_or_mem_operand" "r,rm")
(match_operand:SI 3 "general_operand" "rm,O")]))]
""
"@
cam%1 %2,%3\;%_tdza %0,%0\;%_%_movei %0,1
skip%1 %@%2\;%_tdza %0,%0\;%_%_movei %0,1"
[(set_attr "length" "3")])
(define_insn "*snesf"
[(set (match_operand:SI 0 "register_operand" "=r,x")
(ne:SI (match_operand:SF 1 "reg_or_mem_operand" "0,rm")
(match_operand:SF 2 "immediate_operand" "R,R")))]
""
"@
skipe %@%0\;%_movei %0,1
skipe %0,%1\;%_movei %0,1"
[(set_attr "length" "2")])
(define_insn "*sltsf"
[(set (match_operand:SI 0 "register_operand" "=r")
(lt:SI (match_operand:SF 1 "register_operand" "0")
(match_operand:SF 2 "immediate_operand" "R")))]
""
"lsh %0,-43")
(define_insn "*sgesf"
[(set (match_operand:SI 0 "register_operand" "=r")
(ge:SI (match_operand:SF 1 "register_operand" "0")
(match_operand:SF 2 "immediate_operand" "R")))]
""
"lsh %0,-43\;xori %0,1"
[(set_attr "length" "2")])
(define_insn "*sccsf"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(match_operator:SI 1 "pdp10_comparison_operator"
[(match_operand:SF 2 "reg_or_mem_operand" "r,rm")
(match_operand:SF 3 "general_operand" "rm,R")]))]
""
"@
cam%1 %2,%3\;%_tdza %0,%0\;%_%_movei %0,1
skip%1 %@%2\;%_tdza %0,%0\;%_%_movei %0,1"
[(set_attr "length" "3")])
(define_insn "*snedf"
[(set (match_operand:SI 0 "register_operand" "=x")
(ne:SI (match_operand:DF 1 "reg_or_mem_operand" "ro")
(match_operand:DF 2 "pdp10_const_double_0_operand" "")))]
""
"skipn %@%1\;%_skipe %0,%Z1\;%_%_movei %0,1"
[(set_attr "length" "3")])
(define_insn "*sltdf"
[(set (match_operand:SI 0 "register_operand" "=r")
(lt:SI (match_operand:DF 1 "register_operand" "0")
(match_operand:DF 2 "immediate_operand" "R")))]
""
"lsh %0,-43")
(define_insn "*sgedf"
[(set (match_operand:SI 0 "register_operand" "=r")
(ge:SI (match_operand:DF 1 "register_operand" "0")
(match_operand:DF 2 "immediate_operand" "R")))]
""
"lsh %0,-43\;xori %0,1"
[(set_attr "length" "2")])
;; (define_expand "cmovsi6" ...)
;; (define_expand "cmovsf6" ...)
;; Reload can't handle JUMP_INSNs (such as this one) with spilled
;; register outputs. Therefore, this pattern must have a memory
;; alternative for operand 3.
(define_insn "*move_and_skipsi"
[(set (pc)
(if_then_else (match_operator 0 "pdp10_comparison_operator"
[(match_operand:SI 1 "reg_or_mem_operand" "r,rm,r,m")
(const_int 0)])
(label_ref (match_operand 2 "" ""))
(pc)))
;; The predicate is "preferably_register_operand" so that memory
;; operands are invalid until after register allocation. The
;; memory constraint is just there as a last resort when operand 3
;; is spilled to stack. The "r" constraint is there to allow
;; accumulator 0.
(set (match_operand:SI 3 "preferably_register_operand" "=1,x,rm,!rm")
(match_dup 1))]
""
{
if (which_alternative == 0)
return "jump%0 %1,%F2";
pdp10_remove_unnecessary_label (insn, operands[2]);
switch (get_attr_length (insn))
{
case 1:
return "skip%0 %3,%1";
case 2:
if (which_alternative == 2)
return "movem %1,%3\;jump%0 %1,%F2";
else if (REGNO (operands[3]) == 0)
return "move %3,%1\;jump%0 %3,%F2";
else
{
output_asm_insn ("skip%R0 %3,%1", operands);
return pdp10_output_jrst (operands[2]);
}
/* FIXME: is the use of a fixed scratch register avoidable? */
case 3:
return "move 0,%1\;movem 0,%3\;jump%0 0,%F2";
default:
abort ();
}
}
[(set (attr "length")
(cond [(eq_attr "alternative" "0") (const_int 1)
(eq_attr "alternative" "2") (const_int 2)
(eq_attr "alternative" "3") (const_int 3)
(eq (minus (match_dup 2) (pc)) (const_int 1)) (const_int 1)]
(const_int 2)))
(set_attr "skip" "yes")])
; (define_insn "*move_and_skipsi"
; [(set (pc)
; (if_then_else (match_operator 0 "pdp10_comparison_operator"
; [(match_operand:SI 1 "reg_or_mem_operand" "r,rm,rm")
; (const_int 0)])
; (label_ref (match_operand 2 "" ""))
; (pc)))
; ;; The predicate is "preferably_register_operand" so that memory
; ;; operands are invalid until after register allocation. The
; ;; memory constraint is just there as a last resort when operand 3
; ;; is spilled to stack. The "r" constraint is there to allow
; ;; accumulator 0.
; (set (match_operand:SI 3 "preferably_register_operand" "=1,x,!rm")
; (match_dup 1))]
; ""
; {
; if (which_alternative == 0)
; return "jump%0 %1,%F2";
; pdp10_remove_unnecessary_label (insn, operands[2]);
; switch (get_attr_length (insn))
; {
; case 1:
; return "skip%0 %3,%1";
; case 2:
; if (REGNO (operands[3]) == 0)
; return "move %3,%1\;jump%0 %3,%F2";
; else
; {
; output_asm_insn ("skip%R0 %3,%1", operands);
; return pdp10_output_jrst (operands[2]);
; }
; /* FIXME: is the use of a fixed scratch register avoidable? */
; case 3:
; return "move 0,%1\;movem 0,%3\;jump%0 0,%F2";
; default:
; abort ();
; }
; }
; [(set (attr "length")
; (cond [(eq_attr "alternative" "0") (const_int 1)
; (eq_attr "alternative" "2") (const_int 3)
; (eq (minus (match_dup 2) (pc)) (const_int 1)) (const_int 1)]
; (const_int 2)))
; (set_attr "skip" "yes")])
;; Reload can't handle JUMP_INSNs (such as this one) with spilled
;; register outputs. Therefore, this pattern must have a memory
;; alternative for operand 4.
(define_insn "*move_and_skipsf"
[(set (pc)
(if_then_else
(match_operator 0 "pdp10_comparison_operator"
[(match_operand:SF 1 "reg_or_mem_operand" "rm,rm,rm")
(match_operand:SF 2 "pdp10_const_double_0_operand" "")])
(label_ref (match_operand 3 "" ""))
(pc)))
;; The predicate is "preferably_register_operand" so that memory
;; operands are invalid until after register allocation pass. The
;; memory constraint is just there as a last resort when operand 3
;; is spilled to stack. The "r" constraint is there to allow
;; accumulator 0.
(set (match_operand:SF 4 "preferably_register_operand" "=1,x,!rm")
(match_dup 1))]
""
{
if (which_alternative == 0)
return "jump%0 %1,%F3";
pdp10_remove_unnecessary_label (insn, operands[3]);
switch (get_attr_length (insn))
{
case 1:
return "skip%0 %4,%1";
case 2:
if (REGNO (operands[3]) == 0)
return "move %4,%1\;jump%0 %4,%F3";
else
{
output_asm_insn ("skip%R0 %4,%1", operands);
return pdp10_output_jrst (operands[3]);
}
/* FIXME: is the use of a fixed scratch register avoidable? */
case 3:
return "move 0,%1\;movem 0,%4\;jump%0 0,%F3";
default:
abort ();
}
}
[(set (attr "length")
(cond [(eq_attr "alternative" "0") (const_int 1)
(eq_attr "alternative" "2") (const_int 3)
(eq (minus (match_dup 3) (pc)) (const_int 1)) (const_int 1)]
(const_int 2)))
(set_attr "skip" "yes")])
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Integer Arithmetic
(define_expand "addsi3"
[(set (match_operand:SI 0 "reg_or_mem_operand" "")
(plus:SI (match_operand:SI 1 "reg_or_mem_operand" "")
(match_operand:SI 2 "general_operand" "")))]
""
;; Make sure that for a MEM + x, x can only be a register or +/-1.
"if (memory_operand (operands[1], SImode)
&& !(register_operand (operands[2], SImode)
|| (const_int_operand (operands[2], SImode)
&& (INTVAL (operands[2]) == 1 || INTVAL (operands[2]) == -1))))
operands[2] = force_reg (SImode, operands[2]);")
(define_insn "*addsi3"
[(set (match_operand:SI 0 "reg_or_mem_operand" "=r,r,r,r,r,m,m,m")
(plus:SI (match_operand:SI 1 "reg_or_mem_operand" "%0,0,0,r,0,0,0,0")
;; ADDRESS: an S constraint for the addi case would allow
;; a symbol.
(match_operand:SI 2 "general_operand" "rm,I,J,S,i,r,Q,M")))]
""
; ;; Make sure that for a MEM + x, x can only be a register or +/-1.
; "!(memory_operand (operands[1], SImode)
; && !(register_operand (operands[2], SImode)
; || (const_int_operand (operands[2], SImode)
; && (INTVAL (operands[2]) == 1 || INTVAL (operands[2]) == -1))))"
"@
add %0,%2
addi %0,%2
subi %0,%N2
xmovei %0,%2(%1)
add %0,[%X2]
addm %2,%0
aos %@%0
sos %@%0")
(define_insn "*ADDI_reg"
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (and:SI (match_operand:SI 1 "register_operand" "x")
(const_int RIGHT_HALF))
(match_operand:SI 2 "register_operand" "0")))]
""
"addi %0,(%1)")
(define_insn "*ADDI_const_plus_reg"
[(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "x")
(match_operand:SI 2 "const_int_operand" "I"))
(const_int RIGHT_HALF))
(match_operand:SI 3 "register_operand" "0")))]
"pdp10_const_ok_for_letter_p (INTVAL (operands[2]), 'I')"
"addi %0,%2(%1)")
(define_insn "*ADDB1"
[(set (match_operand:SI 0 "memory_operand" "+m")
(plus:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
(set (match_operand:SI 2 "register_operand" "=1")
(plus:SI (match_dup 0) (match_dup 1)))]
""
"addb %1,%0")
(define_insn "*ADDB2"
[(set (match_operand:SI 0 "memory_operand" "+m")
(plus:SI (match_operand:SI 1 "register_operand" "r") (match_dup 0)))
(set (match_operand:SI 2 "register_operand" "=1")
(plus:SI (match_dup 1) (match_dup 0)))]
""
"addb %1,%0")
(define_insn "*AOS_and_move"
[(set (match_operand:SI 0 "reg_or_mem_operand" "+rm")
(plus:SI (match_dup 0) (const_int 1)))
(set (match_operand:SI 1 "register_operand" "=x")
(plus:SI (match_dup 0) (const_int 1)))]
""
"aos %1,%0")
(define_expand "adddi3"
[(set (match_operand:DI 0 "register_operand" "")
(plus:DI (match_operand:DI 1 "register_operand" "")
(match_operand:DI 2 "general_operand" "")))]
"TARGET_KL10up && TARGET_71BIT"
"")
(define_insn "*adddi3"
[(set (match_operand:DI 0 "reg_or_mem_operand" "=r,r,r,r,o,o,o")
(plus:DI (match_operand:DI 1 "reg_or_mem_operand" "%0,0,0,0,0,0,0")
(match_operand:DI 2 "general_operand" "ro,I,J,i,r,Q,M")))]
"0 && !TARGET_71BIT"
"@
jfcl 17,.+1\;add %Z0,%Z2\;jcry0 [aoja %0,.+1]\;add %0,%2
jfcl 17,.+1\;addi %Z0,%2\;jcry0 [aoja %0,.+1]
jfcl 17,.+1\;subi %Z0,%N2\;jcry0 .+2\;%_subi %0,1
jfcl 17,.+1\;add %Z0,[%B2]\;jcry0 [aoja %0,.+1]\;add %0,[%A2]
jfcl 17,.+1\;addm %Z2,%Z0\;jcry0 [aos %0\;jrst .+1]\;add %2,%0
jfcl 17,.+1\;aos %Z0\;jcry0 [aos %0\;jrst .+1]\;aos %0
jfcl 17,.+1\;sos %Z0\;jcry0 .+2\;sos %0\;sos %0"
[(set_attr "length" "4,3,4,4,4,4,5")])
(define_insn "*DADD"
[(set (match_operand:DI 0 "register_operand" "=r,r")
(plus:DI (match_operand:DI 1 "register_operand" "%0,0")
(match_operand:DI 2 "general_operand" "rm,i")))]
"TARGET_71BIT && TARGET_KL10up"
"@
dadd %0,%2
dadd %0,[%D2]")
(define_expand "subsi3"
[(set (match_operand:SI 0 "reg_or_mem_operand" "")
(minus:SI (match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "general_operand" "")))]
""
"if (!register_operand (operands[1], SImode))
operands[1] = force_reg (SImode, operands[1]);")
(define_insn "*subsi3"
[(set (match_operand:SI 0 "reg_or_mem_operand" "=r,m")
(minus:SI (match_operand:SI 1 "register_operand" "0,r")
(match_operand:SI 2 "general_operand" "rm,0")))]
""
"@
sub %0,%2
subm %1,%0")
(define_insn "*SUBI_reg"
[(set (match_operand:SI 0 "register_operand" "=r")
(minus:SI (match_operand:SI 1 "register_operand" "0")
(and:SI (match_operand:SI 2 "register_operand" "x")
(const_int RIGHT_HALF))))]
""
"subi %0,(%2)")
(define_insn "*SUBI_const_plus_reg"
[(set (match_operand:SI 0 "register_operand" "=r")
(minus:SI (match_operand:SI 1 "register_operand" "0")
(and:SI (plus:SI
(match_operand:SI 2 "register_operand" "x")
(match_operand:SI 3 "const_int_operand" "I"))
(const_int RIGHT_HALF))))]
"pdp10_const_ok_for_letter_p (INTVAL (operands[3]), 'I')"
"subi %0,%3(%2)")
(define_insn "*SUBB"
[(set (match_operand:SI 0 "memory_operand" "+m")
(minus:SI (match_operand:SI 1 "register_operand" "r") (match_dup 0)))
(set (match_operand:SI 2 "register_operand" "=1")
(minus:SI (match_dup 1) (match_dup 0)))]
""
"subb %1,%0")
(define_insn "*SOS_and_move"
[(set (match_operand:SI 0 "reg_or_mem_operand" "+rm")
(plus:SI (match_dup 0) (const_int -1)))
(set (match_operand:SI 1 "register_operand" "=x")
(plus:SI (match_dup 0) (const_int -1)))]
""
"sos %1,%0")
(define_expand "subdi3"
[(set (match_operand:DI 0 "register_operand" "")
(minus:DI (match_operand:DI 1 "register_operand" "")
(match_operand:DI 2 "general_operand" "")))]
"TARGET_KL10up && TARGET_71BIT"
"")
(define_insn "*subdi3"
[(set (match_operand:DI 0 "register_operand" "=r,o")
(minus:DI (match_operand:DI 1 "register_operand" "%0,0")
(match_operand:DI 2 "reg_or_mem_operand" "ro,r")))]
"0 && !TARGET_71BIT"
"@
jfcl 17,.+1\;sub %Z0,%Z2\;jcry0 .+2\;%_subi %0,1\;sub %0,%2
jfcl 17,.+1\;subm %Z2,%Z0\;jcry0 .+2\;%_sos %0\;subm %2,%0"
[(set_attr "length" "5,5")])
(define_insn "*DSUB"
[(set (match_operand:DI 0 "register_operand" "=r,r")
(minus:DI (match_operand:DI 1 "register_operand" "0,0")
(match_operand:DI 2 "reg_or_mem_operand" "rm,i")))]
"TARGET_71BIT && TARGET_KL10up"
"@
dsub %0,%2
dsub %0,[%D2]")
(define_insn "mulsi3"
[(set (match_operand:SI 0 "reg_or_mem_operand" "=r,r,r,m")
(mult:SI (match_operand:SI 1 "reg_or_mem_operand" "%0,0,0,0")
(match_operand:SI 2 "general_operand" "rm,I,i,r")))]
""
"@
imul %0,%2
imuli %0,%2
imul %0,[%2]
imulm %2,%0")
(define_insn "*IMULI_reg"
[(set (match_operand:SI 0 "register_operand" "=r")
(mult:SI (and:SI (match_operand:SI 1 "register_operand" "x")
(const_int RIGHT_HALF))
(match_operand:SI 2 "register_operand" "0")))]
""
"imuli %0,(%1)")
(define_insn "*IMULI_const_plus_reg"
[(set (match_operand:SI 0 "register_operand" "=r")
(mult:SI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "x")
(match_operand:SI 2 "const_int_operand" "I"))
(const_int RIGHT_HALF))
(match_operand:SI 3 "register_operand" "0")))]
"pdp10_const_ok_for_letter_p (INTVAL (operands[2]), 'I')"
"imuli %0,%2(%1)")
(define_insn "*IMULB1"
[(set (match_operand:SI 0 "memory_operand" "+m")
(mult:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
(set (match_operand:SI 2 "register_operand" "=1")
(mult:SI (match_dup 0) (match_dup 1)))]
""
"imulb %1,%0")
(define_insn "*IMULB2"
[(set (match_operand:SI 0 "memory_operand" "+m")
(mult:SI (match_operand:SI 1 "register_operand" "r") (match_dup 0)))
(set (match_operand:SI 2 "register_operand" "=1")
(mult:SI (match_dup 1) (match_dup 0)))]
""
"imulb %1,%0")
(define_expand "mulsidi3"
[(set (match_operand:DI 0 "register_operand" "")
(mult:DI
(sign_extend:DI (match_operand:SI 1 "register_operand" ""))
(sign_extend:DI (match_operand:SI 2 "general_operand" ""))))]
"TARGET_71BIT"
"")
(define_insn "*mulsidi3"
[(set (match_operand:DI 0 "register_operand" "=r,r,r")
(mult:DI
(sign_extend:DI (match_operand:SI 1 "register_operand" "%0,0,0"))
(sign_extend:DI (match_operand:SI 2 "general_operand" "rm,I,i"))))]
"TARGET_71BIT"
"@
mul %0,%2
muli %0,%2
mul %0,[%2]")
(define_insn "MUL"
[(set (match_operand:DI 0 "register_operand" "=r,r,r")
(unspec:DI
[(sign_extend:DI (match_operand:SI 1 "register_operand" "%0,0,0"))
(sign_extend:DI (match_operand:SI 2 "general_operand" "rm,I,i"))]
UNSPEC_MUL71))]
""
"@
mul %0,%2
muli %0,%2
mul %0,[%2]")
(define_expand "smulsi3_highpart"
[(set (match_dup 3)
(truncate:SI
(lshiftrt:DI
(mult:DI
(sign_extend:DI (match_operand:SI 1 "register_operand" "%r"))
(sign_extend:DI (match_operand:SI 2 "reg_or_mem_operand" "0")))
(const_int 35))))
(set (match_operand:SI 0 "reg_or_mem_operand" "=rm")
(ashiftrt:SI (match_dup 3) (neg:SI (const_int -1))))]
"0"
"operands[3] = gen_reg_rtx (SImode);")
(define_insn "*smulsi3_highpart"
[(set (match_operand:SI 0 "register_operand" "=r")
(truncate:SI
(lshiftrt:DI
(mult:DI
(sign_extend:DI (match_operand:SI 1 "register_operand" "%0"))
(sign_extend:DI (match_operand:SI 2 "register_operand" "r")))
(const_int 36))))]
"0"
"jfcl .+1\;mulm %2,%0\;jov [movsi %0,200000\;%_%_%_%_%_jrst .+2]\;ash %0,-1"
[(set_attr "length" "4")])
(define_insn "*smulsi3_highpart_71"
[(set (match_operand:SI 0 "reg_or_mem_operand" "=rm")
(truncate:SI
(lshiftrt:DI
(mult:DI
(sign_extend:DI (match_operand:SI 1 "register_operand" "%r"))
(sign_extend:DI (match_operand:SI 2 "reg_or_mem_operand" "0")))
(const_int 35))))]
"0"
"mulm %1,%0")
(define_expand "muldi3"
[(set (match_operand:DI 0 "register_operand" "")
(mult:DI (match_operand:DI 1 "register_operand" "")
(match_operand:DI 2 "reg_or_mem_operand" "")))]
"0"
"{
rtx temp = gen_reg_rtx (TImode);
emit_move_insn (gen_rtx_SUBREG (DImode, temp, 0), operands[1]);
emit_insn (gen_DMUL (temp, gen_rtx_SUBREG (DImode, temp, 8),
operands[2]));
emit_insn (gen_ashlsi3 (gen_rtx_SUBREG (SImode, temp, 8),
gen_rtx_SUBREG (SImode, temp, 8),
GEN_INT (1)));
emit_insn (gen_lshrdi3 (gen_rtx_SUBREG (DImode, temp, 4),
gen_rtx_SUBREG (DImode, temp, 4),
GEN_INT (1)));
emit_insn (gen_ashlsi3 (gen_rtx_SUBREG (SImode, temp, 12),
gen_rtx_SUBREG (SImode, temp, 12),
GEN_INT (1)));
emit_insn (gen_lshrdi3 (gen_rtx_SUBREG (DImode, temp, 8),
gen_rtx_SUBREG (DImode, temp, 8),
GEN_INT (1)));
emit_insn (gen_TRNE_TLO (gen_rtx_SUBREG (SImode, temp, 8),
gen_rtx_SUBREG (SImode, temp, 8),
gen_rtx_SUBREG (SImode, temp, 12)));
DONE;
}")
(define_insn "TRNE_TLO"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "register_operand" "r")]
UNSPEC_TRNE_TLO))]
""
"trne %2,1\;%_tlo %0,400000"
[(set_attr "length" "2")])
(define_expand "mulditi3"
[(set (match_operand:TI 0 "register_operand" "=r,r")
(mult:TI
(sign_extend:TI (match_operand:DI 1 "register_operand" "%0,0"))
(sign_extend:TI (match_operand:DI 2 "general_operand" "rm,i"))))]
"TARGET_71BIT && TARGET_KL10up"
"")
(define_insn "DMUL"
[(set (match_operand:TI 0 "register_operand" "=r,r")
(mult:TI
(sign_extend:TI (match_operand:DI 1 "register_operand" "%0,0"))
(sign_extend:TI (match_operand:DI 2 "general_operand" "rm,i"))))]
"TARGET_71BIT && TARGET_KL10up"
"@
dmul %0,%2
dmul %0,[%D2]")
(define_insn "IDIV"
[(set (subreg:SI (match_operand:DI 0 "register_operand" "=r,r,r") 0)
(div:SI (match_operand:SI 1 "register_operand" "0,0,0")
(match_operand:SI 2 "general_operand" "rm,I,i")))
(set (subreg:SI (match_dup 0) 4)
(mod:SI (match_dup 1) (match_dup 2)))]
""
"@
idiv %0,%2
idivi %0,%2
idiv %0,[%2]")
(define_insn "IDIVM"
[(set (match_operand:SI 0 "reg_or_mem_operand" "=rm")
(div:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "reg_or_mem_operand" "0")))]
""
"idivm %1,%0")
;; IDIVI with indexing missing.
;; IDIVB missing.
(define_expand "divsi3"
[(set (match_operand:SI 0 "reg_or_mem_operand" "")
(div:SI (match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "general_operand" "")))]
""
"if (immediate_operand (operands[2], SImode))
{
rtx temp = gen_reg_rtx (DImode);
rtx temp0 = gen_rtx_SUBREG (SImode, temp, 0);
emit_move_insn (temp0, operands[1]);
emit_insn (gen_IDIV (temp, temp0, operands[2]));
emit_move_insn (operands[0], temp0);
}
else
emit_insn (gen_IDIVM (operands[0], operands[1], operands[2]));
DONE;")
(define_expand "modsi3"
[(set (match_operand:SI 0 "register_operand" "")
(mod:SI (match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "general_operand" "")))]
""
"{
rtx temp = gen_reg_rtx (DImode);
rtx temp0 = gen_rtx_SUBREG (SImode, temp, 0);
rtx temp1 = gen_rtx_SUBREG (SImode, temp, 4);
emit_move_insn (temp0, operands[1]);
emit_insn (gen_IDIV (temp, temp0, operands[2]));
emit_move_insn (operands[0], temp1);
DONE;
}")
;; This is disabled, since it doesn't seem to have any advantages over
;; the `divsi3' and `modsi3' patterns.
(define_expand "_divmodsi4"
[(parallel [(set (match_operand:SI 0 "reg_or_mem_operand" "")
(div:SI (match_operand:SI 1 "reg_or_mem_operand" "")
(match_operand:SI 2 "general_operand" "")))
(set (match_operand:SI 3 "reg_or_mem_operand" "")
(mod:SI (match_dup 1) (match_dup 2)))])]
"0"
"{
rtx temp = gen_reg_rtx (DImode);
rtx temp0 = gen_rtx_SUBREG (SImode, temp, 0);
rtx temp1 = gen_rtx_SUBREG (SImode, temp, 4);
emit_move_insn (temp0, operands[1]);
emit_insn (gen_IDIV (temp, temp0, operands[2]));
emit_move_insn (operands[0], temp0);
emit_move_insn (operands[3], temp1);
DONE;
}")
(define_insn "*DIV"
[(set (subreg:SI (match_operand:DI 0 "register_operand" "=r,r,r") 0)
(truncate:SI
(div:DI
(match_operand:DI 1 "register_operand" "0,0,0")
(sign_extend:DI (match_operand:SI 2 "general_operand" "rm,I,i")))))
(set (subreg:SI (match_dup 0) 4)
(truncate:SI (mod:DI (match_dup 1) (sign_extend:DI (match_dup 2)))))]
"TARGET_71BIT"
"@
div %0,%2
divi %0,%2
div %0,[%D2]")
(define_insn "*DIVM"
[(set (match_operand:SI 0 "reg_or_mem_operand" "=rm")
(truncate:SI
(div:DI
(match_operand:DI 1 "register_operand" "r")
(sign_extend:DI (match_operand:SI 2 "memory_operand" "0")))))]
"TARGET_71BIT"
"divm %1,%0")
;; DIVB missing.
(define_insn "DDIV"
[(set (subreg:DI (match_operand:TI 0 "register_operand" "=r,r") 0)
(truncate:DI
(div:TI
(match_operand:TI 1 "register_operand" "0,0")
(sign_extend:TI (match_operand:DI 2 "general_operand" "rm,i")))))
(set (subreg:DI (match_dup 0) 8)
(truncate:DI (mod:TI (match_dup 1) (sign_extend:TI (match_dup 2)))))]
"TARGET_71BIT"
"@
ddiv %0,%2
ddiv %0,[%D2]")
(define_expand "divmoddi4"
[(parallel [(set (match_operand:DI 0 "reg_or_mem_operand" "")
(div:DI (match_operand:DI 1 "register_operand" "")
(match_operand:DI 2 "general_operand" "")))
(set (match_operand:DI 3 "register_operand" "")
(mod:DI (match_dup 1) (match_dup 2)))])]
"TARGET_71BIT"
"{
rtx temp = gen_reg_rtx (TImode);
emit_move_insn (gen_rtx_SUBREG (SImode, temp, 0),
gen_rtx_SUBREG (SImode, operands[1], 0));
emit_insn (gen_ashrsi3 (gen_rtx_SUBREG (SImode, temp, 0),
gen_rtx_SUBREG (SImode, temp, 0),
GEN_INT (35)));
emit_move_insn (gen_rtx_SUBREG (SImode, temp, 4),
gen_rtx_SUBREG (SImode, temp, 0));
emit_move_insn (gen_rtx_SUBREG (DImode, temp, 8), operands[1]);
emit_insn (gen_DDIV (temp, temp, operands[2]));
emit_move_insn (operands[0], gen_rtx_SUBREG (DImode, temp, 0));
emit_move_insn (operands[3], gen_rtx_SUBREG (DImode, temp, 8));
DONE;
}")
(define_insn "udivsi3"
[(set (match_operand:SI 0 "reg_or_mem_operand" "=r,r,r,m")
(udiv:SI (match_operand:SI 1 "register_operand" "0,0,0,r")
(match_operand:SI 2 "general_operand" "I,i,rm,0")))]
"TARGET_XKL2"
"@
extend %0,[uidivi %2]
extend %0,[uidiv [%2]]
extend %0,[uidiv %2]
extend %1,[uidivm %0]")
;; UIDIVI with indexing missing.
;; UIDIVB missing.
(define_insn "umodsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r,r,m")
(umod:SI (match_operand:SI 1 "register_operand" "0,0,0,r")
(match_operand:SI 2 "general_operand" "I,i,rm,0")))]
"TARGET_XKL2"
"@
extend %0,[uimodi %2]
extend %0,[uimod [%2]]
extend %0,[uimod %2]
extend %1,[uimodm %0]")
;; UIMODI with indexing missing.
;; UIMODB missing.
(define_insn "negsi2"
[(set (match_operand:SI 0 "reg_or_mem_operand" "=r,m,r,m")
(neg:SI (match_operand:SI 1 "general_operand" "rm,r,I,0")))]
""
"@
movn %0,%1
movnm %1,%0
movni %0,%N1
movns %0")
(define_insn "*MOVNI_reg"
[(set (match_operand:SI 0 "register_operand" "=r")
(neg:SI (and:SI (match_operand:SI 1 "register_operand" "r")
(const_int RIGHT_HALF))))]
""
"movni %0,(%1)")
(define_insn "*MOVNI_const_plus_reg"
[(set (match_operand:SI 0 "register_operand" "=r")
(neg:SI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "const_int_operand" "I"))
(const_int RIGHT_HALF))))]
"pdp10_const_ok_for_letter_p (INTVAL (operands[2]), 'I')"
"movni %0,%2(%1)")
(define_insn "*MOVNS"
[(set (match_operand:SI 0 "reg_or_mem_operand" "+rm")
(neg:SI (match_dup 0)))
(set (match_operand:SI 1 "register_operand" "=x")
(neg:SI (match_dup 0)))]
""
"movns %1,%0")
(define_expand "negdi2"
[(set (match_operand:DI 0 "reg_or_mem_operand" "")
(neg:DI (match_operand:DI 1 "reg_or_mem_operand" "")))]
"TARGET_KI10up && TARGET_71BIT"
"")
(define_insn "*negdi2"
[(set (match_operand:DI 0 "register_operand" "=r,r")
(neg:DI (match_operand:DI 1 "reg_or_mem_operand" "0,ro")))]
"!TARGET_71BIT"
"@
setca %0,\;jumpe %Z0,[aoja %0,.+2]\;%_movn %Z0,%Z0
setcm %0,%1\;movn %Z0,%Z1\;jumpe %Z0,[aoja %0,.+1]"
[(set_attr "length" "3,3")])
(define_insn "*DMOVN"
[(set (match_operand:DI 0 "register_operand" "=r")
(neg:DI (match_operand:DI 1 "reg_or_mem_operand" "rm")))]
"TARGET_71BIT && TARGET_KI10up"
"dmovn %0,%1\;tlne %0,400000\;%_tlo %Z0,400000"
[(set_attr "length" "3")])
(define_insn "abssi2"
[(set (match_operand:SI 0 "reg_or_mem_operand" "=r,m,m")
(abs:SI (match_operand:SI 1 "reg_or_mem_operand" "rm,r,0")))]
""
"@
movm %0,%1
movmm %1,%0
movms %0")
(define_insn "*MOVMS"
[(set (match_operand:SI 0 "reg_or_mem_operand" "+rm")
(abs:SI (match_dup 0)))
(set (match_operand:SI 1 "register_operand" "=x")
(abs:SI (match_dup 0)))]
""
"movms %1,%0")
(define_insn "smaxsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,x,x,x")
(smax:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,r,r,r,r")
(match_operand:SI 2 "general_operand" "rm,I,M,i,0,O,I,rm")))]
""
"@
camge %1,%2\;%_move %0,%2
caige %1,%2\;%_movei %0,%2
camge %1,[%2]\;%_seto %0,
camge %1,[%2]\;%_move %0,[%2]
camle %1,%2\;%_move %0,%1
skipge %0,%1\;%_movei %0,0
caile %1,%2\;%_skipa %0,%1\;%_%_movei %0,%2
camle %1,%2\;%_skipa %0,%1\;%_%_move %0,%2"
[(set_attr "length" "2,2,2,2,2,2,3,3")])
(define_expand "umaxsi3"
[(set (match_dup 3)
(xor:SI (match_operand:SI 1 "reg_or_mem_operand" "")
(const_int SIGNBIT)))
(set (match_dup 4)
(xor:SI (match_operand:SI 2 "reg_or_mem_operand" "")
(const_int SIGNBIT)))
(set (match_operand:SI 0 "register_operand" "")
(if_then_else:SI
(ge (match_dup 3) (match_dup 4))
(match_dup 1)
(match_dup 2)))]
""
"operands[3] = gen_reg_rtx (SImode);
operands[4] = gen_reg_rtx (SImode);")
(define_insn "*umaxsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r,x")
(if_then_else:SI
(ge (match_operand:SI 3 "register_operand" "r,r,r")
(match_operand:SI 4 "reg_or_mem_operand" "rm,rm,rm"))
(match_operand:SI 1 "reg_or_mem_operand" "0,rm,rm")
(match_operand:SI 2 "reg_or_mem_operand" "rm,0,rm")))]
""
"@
camge %3,%4\;%_move %0,%2
camle %3,%4\;%_move %0,%1
camle %3,%4\;%_skipa %0,%1\;%_%_move %0,%2"
[(set_attr "length" "2,2,3")])
(define_insn "sminsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r,r,x,x,x")
(smin:SI (match_operand:SI 1 "register_operand" "%0,0,0,0,r,r,r,r")
(match_operand:SI 2 "general_operand" "rm,I,M,i,0,O,I,rm")))]
""
"@
camle %1,%2\;%_move %0,%2
caile %1,%2\;%_movei %0,%2
camle %1,[%2]\;%_seto %0,
camle %1,[%2]\;%_move %0,[%2]
camge %1,%2\;%_move %0,%1
skiple %0,%1\;%_movei %0,0
caige %1,%2\;%_skipa %0,%1\;%_%_movei %0,%2
camge %1,%2\;%_skipa %0,%1\;%_%_move %0,%2"
[(set_attr "length" "2,2,2,2,2,2,3,3")])
(define_expand "uminsi3"
[(set (match_dup 3)
(xor:SI (match_operand:SI 1 "reg_or_mem_operand" "")
(const_int SIGNBIT)))
(set (match_dup 4)
(xor:SI (match_operand:SI 2 "reg_or_mem_operand" "")
(const_int SIGNBIT)))
(set (match_operand:SI 0 "register_operand" "")
(if_then_else:SI
(le (match_dup 3) (match_dup 4))
(match_dup 1)
(match_dup 2)))]
""
"operands[3] = gen_reg_rtx (SImode);
operands[4] = gen_reg_rtx (SImode);")
(define_insn "*uminsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r,x")
(if_then_else:SI
(le (match_operand:SI 3 "register_operand" "r,r,r")
(match_operand:SI 4 "reg_or_mem_operand" "rm,rm,rm"))
(match_operand:SI 1 "reg_or_mem_operand" "0,rm,rm")
(match_operand:SI 2 "reg_or_mem_operand" "rm,0,rm")))]
""
"@
camle %3,%4\;%_move %0,%2
camge %3,%4\;%_move %0,%1
camge %3,%4\;%_skipa %0,%1\;%_%_move %0,%2"
[(set_attr "length" "2,2,3")])
;; The JFFO instruction searches from the most significant bit while
;; FFS searches from the least significant bit. The bit index and
;; treatment of zero also differ.
(define_expand "ffssi2"
[(set (match_operand:SI 0 "register_operand" "")
(ffs:SI (match_operand:SI 1 "register_operand" "")))]
"TARGET_KA10up"
"if (!TARGET_XKL2)
{
rtx t1 = gen_reg_rtx (SImode);
rtx t2 = gen_reg_rtx (SImode);
rtx t3 = gen_reg_rtx (DImode);
rtx t4 = gen_reg_rtx (SImode);
rtx label = gen_label_rtx ();
extern int pdp10_expand_ffs;
pdp10_expand_ffs++;
emit_insn (gen_negsi2 (t1, operands[1]));
emit_insn (gen_andsi3 (t2, operands[1], t1));
emit_move_insn (gen_rtx_SUBREG (SImode, t3, 0), t2);
emit_jump_insn (gen_JFFO (t3, gen_rtx_LABEL_REF (Pmode, label)));
emit_move_insn (gen_rtx_SUBREG (SImode, t3, 4),
GEN_INT (36));
emit_label (label);
emit_insn (gen_subsi3 (t4,
gen_rtx_SUBREG (SImode, t3, 4),
GEN_INT (36)));
emit_insn (gen_negsi2 (operands[0], t4));
DONE;
}")
(define_insn "*FFS"
[(set (match_operand:SI 0 "register_operand" "=r")
(ffs:SI (match_operand:SI 1 "reg_or_mem_operand" "rm")))]
"TARGET_XKL2"
"ffs %0,%1")
; (define_expand "popcountsi"
; Sequence taken from HAKMEM.
; LDB B,[014300,,A] ;or MOVE B,A then LSH B,-1
; AND B,[333333,,333333]
; SUB A,B
; LSH B,-1
; AND B,[333333,,333333]
; SUBB A,B ;each octal digit is replaced by number of 1's in it
; LSH B,-3
; ADD A,B
; AND A,[070707,,070707]
; IDIVI A,77 ;casting out 63.'s
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Integer Conversions
; (define_insn "zero_extendqisi2"
; [(set (match_operand:SI 0 "register_operand" "=r")
; (zero_extend:SI (match_operand:QI 1 "register_operand" "r")))]
; ""
; ""
; [(set_attr "length" "0")])
(define_insn "zero_extendqisi2"
[(set (match_operand:SI 0 "register_operand" "=r")
(zero_extend:SI (match_operand:QI 1 "register_operand" "0")))]
""
{
if (zero_extended_p (operands[0], 27, insn))
return "";
else
return "andi %0,777%; zero_extendqisi2";
})
(define_insn "zero_extendhisi2"
[(set (match_operand:SI 0 "register_operand" "=r")
(zero_extend:SI (match_operand:HI 1 "register_operand" "r")))]
""
{
if (REGNO (operands[0]) == REGNO (operands[1])
&& zero_extended_p (operands[0], 18, insn))
return "";
else
return "hrrz %0,%1%; zero_extendhisi2";
})
(define_insn "zero_extendsi"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "const_int_operand" "")]
UNSPEC_ZERO_EXTEND))]
""
{
int extend_bits = INTVAL (operands[2]);
int bitsize = BITS_PER_WORD - extend_bits;
if (zero_extended_p (operands[0], extend_bits, insn))
return "";
else if (extend_bits > 18)
{
operands[2] = GEN_INT ((1 << bitsize) - 1);
return "andi %0,%2";
}
else if (extend_bits == 18)
return "hrrz %0,%0";
else
{
operands[2] = GEN_INT (((1 << extend_bits) - 1) << (18 - extend_bits));
return "tlz %0,%2";
}
})
(define_insn "*extendqisi2_reg"
[(set (match_operand:SI 0 "register_operand" "=r")
(sign_extend:SI
(subreg:QI (match_operand:SI 1 "register_operand" "r") 0)))]
""
{
if (REGNO (operands[0]) == REGNO (operands[1]))
return "";
else
return "move %0,%1%; extendqisi2_reg";
})
(define_expand "extendqisi2"
[(set (match_operand:SI 0 "register_operand" "")
(sign_extend:SI (match_operand:QI 1 "register_operand" "")))]
""
"")
; "if (!TARGET_XKL2)
; {
; rtx op1 = operands[1];
; if (GET_CODE (op1) == SUBREG && SUBREG_BYTE (op1) == 3)
; op1 = SUBREG_REG (op1);
; emit_insn (gen_ashlsi3 (operands[0],
; gen_rtx_SUBREG (SImode, op1, 0),
; GEN_INT (27)));
; emit_insn (gen_ASH_right (operands[0], operands[0], GEN_INT (-27)));
; DONE;
; }")
(define_insn "*extendqisi2"
[(set (match_operand:SI 0 "register_operand" "=r")
(sign_extend:SI (match_operand:QI 1 "register_operand" "0")))]
"!TARGET_XKL2"
{
if (sign_extended_p (operands[0], 27, insn))
return "";
else if (zero_extended_p (operands[0], 27, insn))
return "trne %0,400\;%_orcmi %0,777";
else
return "lsh %0,33\;ash %0,-33";
}
[(set_attr "length" "2")])
(define_insn "*extendqisi2_xkl2"
[(set (match_operand:SI 0 "register_operand" "=r")
(sign_extend:SI (match_operand:QI 1 "register_operand" "0")))]
"TARGET_XKL2"
"extend %0,[sext 9]")
(define_insn "extendhisi2"
[(set (match_operand:SI 0 "register_operand" "=r")
(sign_extend:SI (match_operand:HI 1 "register_operand" "r")))]
""
{
if (sign_extended_p (operands[1], 18, insn)
&& REGNO (operands[0]) == REGNO (operands[1]))
return "";
else
return "hrre %0,%1%; extendhisi2";
})
(define_insn "sign_extendsi"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "const_int_operand" "")]
UNSPEC_SIGN_EXTEND))]
""
{
int extend_bits = INTVAL (operands[2]);
if (sign_extended_p (operands[0], extend_bits, insn))
return "";
else if (zero_extended_p (operands[0], extend_bits, insn))
{
int bitsize = BITS_PER_WORD - extend_bits;
operands[1] = GEN_INT ((HOST_WIDE_INT)1 << (bitsize - 1));
operands[2] = GEN_INT (((HOST_WIDE_INT)1 << bitsize) - 1);
return "trne %0,%1\;%_orcmi %0,%2";
}
else
return "lsh %0,%2\;ash %0,-%2";
})
(define_insn "truncsiqi2"
[(set (match_operand:QI 0 "register_operand" "=r")
(truncate:QI (match_operand:SI 1 "register_operand" "0")))]
""
"andi %0,777%; truncsiqi2")
(define_insn "truncsihi2"
[(set (match_operand:HI 0 "register_operand" "=r")
(truncate:HI (match_operand:SI 1 "register_operand" "r")))]
""
"hrr %0,%1%; truncsihi2")
(define_insn "truncsi"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "register_operand" "0")
(match_operand 2 "const_int_operand" "")]
UNSPEC_TRUNCATE))]
""
{
int bits = BITS_PER_WORD - INTVAL (operands[2]);
if (bits < 18)
{
operands[2] = GEN_INT (((HOST_WIDE_INT)1 << bits) - 1);
return "andi %0,%2%; truncsi";
}
else
{
operands[2] = GEN_INT ((0777777 << (bits - 18)) & 0777777);
return "tlz %0,%2%; truncsi";
}
})
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Shifting and Rotating
(define_insn "real_ashlsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
(unspec:SI
[(match_operand:SI 1 "register_operand" "0,0,0")
(match_operand:SI 2 "general_operand" "x,K,m")]
UNSPEC_REAL_ASHIFT))]
""
"@
ash %0,(%2)
ash %0,%2
ash %0,@%2")
(define_insn "*ASH_left_plus"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI
[(match_operand:SI 1 "register_operand" "0")
(plus:SI (match_operand:SI 2 "register_operand" "x")
(match_operand:SI 3 "immediate_operand" "K"))]
UNSPEC_REAL_ASHIFT))]
""
"ash %0,%3(%2)")
(define_expand "lshrsi3"
[(set (match_dup 3) (neg:SI (match_operand:SI 2 "general_operand" "")))
(set (match_operand:SI 0 "register_operand" "")
(lshiftrt:SI (match_operand:SI 1 "register_operand" "")
(neg:SI (match_dup 3))))]
""
"if (GET_CODE (operands[2]) == CONST_INT)
{
emit_insn (gen_LSH_right (operands[0], operands[1],
GEN_INT (-INTVAL (operands[2]))));
DONE;
}
else
operands[3] = gen_reg_rtx (SImode);")
(define_insn "LSH_right"
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
(lshiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0")
(neg:SI (match_operand:SI 2 "general_operand" "x,K,m"))))]
""
"@
lsh %0,(%2)
lsh %0,%2
lsh %0,@%2")
(define_insn "*LSH_right_plus"
[(set (match_operand:SI 0 "register_operand" "=r")
(lshiftrt:SI
(match_operand:SI 1 "register_operand" "0")
(neg:SI (plus:SI (match_operand:SI 2 "register_operand" "x")
(match_operand:SI 3 "const_int_operand" "K")))))]
""
"lsh %0,%3(%2)")
(define_insn "real_ashldi3"
[(set (match_operand:DI 0 "register_operand" "=r,r,r")
(unspec:DI
[(match_operand:DI 1 "register_operand" "0,0,0")
(match_operand:SI 2 "general_operand" "x,K,m")]
UNSPEC_REAL_ASHIFT))]
"TARGET_71BIT"
"@
ashc %0,(%2)
ashc %0,%2
ashc %0,@%2")
(define_insn "*ASHC"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec:DI
[(match_operand:DI 1 "register_operand" "0")
(plus:SI (match_operand:SI 2 "register_operand" "x")
(match_operand:SI 3 "immediate_operand" "K"))]
UNSPEC_REAL_ASHIFT))]
"TARGET_71BIT"
"ashc %0,%3(%2)")
(define_expand "lshrdi3"
[(set (match_dup 3) (neg:SI (match_operand:SI 2 "general_operand" "")))
(set (match_operand:DI 0 "register_operand" "")
(lshiftrt:DI (match_operand:DI 1 "register_operand" "")
(neg:SI (match_dup 3))))]
""
"if (GET_CODE (operands[2]) == CONST_INT)
{
if (TARGET_71BIT)
emit_insn (gen_LSHC_right_71 (operands[0], operands[1],
GEN_INT (-INTVAL (operands[2]))));
else
emit_insn (gen_LSHC_right (operands[0], operands[1],
GEN_INT (-INTVAL (operands[2]))));
DONE;
}
else
operands[3] = gen_reg_rtx (SImode);")
(define_insn "LSHC_right_71"
[(set (match_operand:DI 0 "register_operand" "=r,r,r")
(lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0,0")
(neg:SI (match_operand:SI 2 "general_operand" "x,K,m"))))]
"TARGET_71BIT"
{
const char *asms[] =
{
"lsh %Z0,1\;lshc %0,(%2)\;lsh %Z0,-1",
"lsh %Z0,1\;lshc %0,%2\;lsh %Z0,-1",
"lsh %Z0,1\;lshc %0,@%2\;lsh %Z0,-1"
};
int n;
if (get_attr_length (insn) == 1)
{
operands[2] = GEN_INT (INTVAL (operands[2]) - 1);
return "lshc %0,%2";
}
/*else if (GET_CODE (operands[2]) == CONST_INT
&& INTVAL (operands[2]) == -1)
return "ashc %0,-1\;tlze %0,400000\;tlz %Z0,400000";*/
else if (GET_CODE (operands[2]) == CONST_INT
&& (n = INTVAL (operands[2])) >= -18)
{
int mask = (0777777 << (18 + n)) & 0777777;
static char insn[100];
snprintf (insn, sizeof insn,
"ashc %%0,%%2\;tlze %%0,%o\;tlz %%Z0,400000",
mask);
return insn;
}
else
return asms[which_alternative];
}
[(set (attr "length")
(if_then_else (and (match_operand 2 "const_int_operand" "")
(ge (symbol_ref "-INTVAL (operands[2])")
(const_int 35)))
(const_int 1)
(const_int 3)))])
(define_insn "LSHC_right"
[(set (match_operand:DI 0 "register_operand" "=r,r,r")
(lshiftrt:DI (match_operand:DI 1 "register_operand" "0,0,0")
(neg:SI (match_operand:SI 2 "general_operand" "x,K,m"))))]
"!TARGET_71BIT"
"@
lshc %0,(%2)
lshc %0,%2
lshc %0,@%2")
(define_insn "*LSHC_right_plus_71"
[(set (match_operand:DI 0 "register_operand" "=r")
(lshiftrt:DI
(match_operand:DI 1 "register_operand" "0")
(neg:SI (plus:SI (match_operand:SI 2 "register_operand" "x")
(match_operand:SI 3 "immediate_operand" "K")))))]
"TARGET_71BIT"
"lsh %Z0,1\;lshc %0,%3(%2)\;lsh %Z0,-1"
[(set_attr "length" "3")])
(define_insn "*LSHC_right_plus"
[(set (match_operand:DI 0 "register_operand" "=r")
(lshiftrt:DI
(match_operand:DI 1 "register_operand" "0")
(neg:SI (plus:SI (match_operand:SI 2 "register_operand" "x")
(match_operand:SI 3 "immediate_operand" "K")))))]
"!TARGET_71BIT"
"lshc %0,%3(%2)")
(define_insn "ashlsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
(ashift:SI (match_operand:SI 1 "register_operand" "0,0,0")
(match_operand:SI 2 "general_operand" "x,K,m")))]
""
"@
lsh %0,(%2)
lsh %0,%2
lsh %0,@%2")
(define_insn "*LSH_left_plus"
[(set (match_operand:SI 0 "register_operand" "=r")
(ashift:SI (match_operand:SI 1 "register_operand" "0")
(plus:SI (match_operand:SI 2 "register_operand" "x")
(match_operand:SI 3 "immediate_operand" "K"))))]
""
"lsh %0,%3(%2)")
(define_expand "ashrsi3"
[(set (match_dup 3) (neg:SI (match_operand:SI 2 "general_operand" "")))
(set (match_operand:SI 0 "register_operand" "")
(ashiftrt:SI (match_operand:SI 1 "register_operand" "")
(neg:SI (match_dup 3))))]
""
"if (GET_CODE (operands[2]) == CONST_INT)
{
emit_insn (gen_ASH_right (operands[0], operands[1],
GEN_INT (-INTVAL (operands[2]))));
DONE;
}
else
operands[3] = gen_reg_rtx (SImode);")
(define_insn "ASH_right"
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
(ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0,0")
(neg:SI (match_operand:SI 2 "general_operand" "x,K,m"))))]
""
"@
ash %0,(%2)
ash %0,%2
ash %0,@%2")
(define_insn "*ASH_right_plus"
[(set (match_operand:SI 0 "register_operand" "=r")
(ashiftrt:SI
(match_operand:SI 1 "register_operand" "0")
(neg:SI (plus:SI (match_operand:SI 2 "register_operand" "x")
(match_operand:SI 3 "immediate_operand" "K")))))]
""
"ash %0,%3(%2)")
(define_expand "ashldi3"
[(set (match_operand:DI 0 "register_operand" "")
(ashift:DI (match_operand:DI 1 "register_operand" "")
(match_operand:SI 2 "general_operand" "")))]
""
"")
(define_insn "*ashldi3"
[(set (match_operand:DI 0 "register_operand" "=r,r,r")
(ashift:DI (match_operand:DI 1 "register_operand" "0,0,0")
(match_operand:SI 2 "general_operand" "x,K,m")))]
"!TARGET_71BIT"
"@
lshc %0,(%2)
lshc %0,%2
lshc %0,@%2")
(define_insn "LSHC_left"
[(set (match_operand:DI 0 "register_operand" "=r,r,r")
(unspec:DI [(match_operand:DI 1 "register_operand" "0,0,0")
(match_operand:SI 2 "general_operand" "x,K,m")]
UNSPEC_LSHC))]
"TARGET_71BIT"
"@
lshc %0,(%2)
lshc %0,%2
lshc %0,@%2")
(define_insn "*ashldi3_71bit"
[(set (match_operand:DI 0 "register_operand" "=r,r,r")
(ashift:DI (match_operand:DI 1 "register_operand" "0,0,0")
(match_operand:SI 2 "general_operand" "x,K,m")))]
"TARGET_71BIT"
{
const char *asms[] =
{
"lsh %Z0,1\;lshc %0,(%2)\;lsh %Z0,-1",
"lsh %Z0,1\;lshc %0,%2\;lsh %Z0,-1",
"lsh %Z0,1\;lshc %0,@%2\;lsh %Z0,-1"
};
switch (get_attr_length (insn))
{
case 3:
operands[2] = GEN_INT (INTVAL (operands[2]) + 1);
output_asm_insn ("lshc %0,%2", operands);
break;
case 4:
{
static char insn[100];
int n = INTVAL (operands[2]);
snprintf (insn, sizeof insn,
n < 18 ? "tlne %%0,%o" : "trne %%0,%o",
0400000 >> (n < 18 ? n: n - 18));
output_asm_insn (insn, operands);
return "%_tloa %0,400000\;%_%_tlz %0,400000\;ashc %0,%2";
}
case 5:
output_asm_insn (asms[which_alternative], operands);
break;
default:
abort ();
}
return "tlne %0,400000\;%_tlo %Z0,400000";
}
[(set (attr "length")
(if_then_else (match_operand 2 "const_int_operand" "")
(if_then_else
(ge (symbol_ref "INTVAL (operands[2])") (const_int 36))
(const_int 3)
(const_int 4))
(const_int 5)))])
(define_insn "*LSHC_left_plus"
[(set (match_operand:DI 0 "register_operand" "=r")
(ashift:DI (match_operand:DI 1 "register_operand" "0")
(plus:SI (match_operand:SI 2 "register_operand" "x")
(match_operand:SI 3 "immediate_operand" "K"))))]
"!TARGET_71BIT"
"lshc %0,%3(%2)")
(define_insn "*LSHC_left_plus_71bit"
[(set (match_operand:DI 0 "register_operand" "=r")
(ashift:DI (match_operand:DI 1 "register_operand" "0")
(plus:SI (match_operand:SI 2 "register_operand" "x")
(match_operand:SI 3 "immediate_operand" "K"))))]
"TARGET_71BIT"
"lsh %Z0,1\;lshc %0,%3(%2)\;lsh %Z0,-1\;tlne %0,400000\;%_tlo %Z0,400000"
[(set_attr "length" "5")])
(define_expand "ashrdi3"
[(set (match_dup 3) (neg:SI (match_operand:SI 2 "general_operand" "")))
(set (match_operand:DI 0 "register_operand" "")
(ashiftrt:DI (match_operand:DI 1 "register_operand" "")
(neg:SI (match_dup 3))))]
""
"if (!TARGET_71BIT)
{
HOST_WIDE_INT mask;
/*rtx op0hi = gen_rtx_SUBREG (SImode, operands[0], 0);
rtx op0lo = gen_rtx_SUBREG (SImode, operands[0], 4);*/
rtx temp = gen_reg_rtx (SImode);
rtx label;
if (GET_CODE (operands[2]) == CONST_INT)
{
int n = INTVAL (operands[2]);
if (n <= 35)
{
label = gen_label_rtx ();
mask = (HOST_WIDE_INT)1 << (35 - n);
emit_insn (gen_lshrdi3 (operands[0], operands[1], operands[2]));
emit_jump_insn (gen_test_and_skip (gen_rtx_EQ (VOIDmode,
NULL_RTX,
NULL_RTX),
gen_rtx_SUBREG (SImode,
operands[0],
0),
gen_int_mode (mask, SImode),
label));
mask = ~(mask - 1);
if (n != 17 && n != 35)
mask <<= 1;
emit_insn (gen_iorsi3 (gen_rtx_SUBREG (SImode, operands[0], 0),
gen_rtx_SUBREG (SImode, operands[0], 0),
gen_int_mode (mask, SImode)));
emit_label (label);
}
else if (n == 36)
/*{
emit_insn (gen_ashrsi3 (gen_rtx_SUBREG (SImode, operands[0], 0),
gen_rtx_SUBREG (SImode, operands[1], 0),
GEN_INT (35)));
emit_move_insn (gen_rtx_SUBREG (SImode, operands[0], 4),
gen_rtx_SUBREG (SImode, operands[1], 0));
}*/
/*{
emit_move_insn (gen_rtx_SUBREG (SImode, operands[0], 4),
gen_rtx_SUBREG (SImode, operands[1], 0));
emit_insn (gen_ashrsi3 (gen_rtx_SUBREG (SImode, operands[0], 0),
gen_rtx_SUBREG (SImode, operands[1], 0),
GEN_INT (35)));
}*/
emit_insn (gen_ashrdi3_36 (operands[0], operands[1]));
else if (n >= 71 && !optimize_size)
emit_insn (gen_sign_extension_di (operands[0], operands[1]));
else
emit_insn (gen_ASHC (operands[0], operands[1], GEN_INT (1 - n)));
DONE;
}
/* Sequence adapted from Hacker's Delight, section 2-6. */
emit_insn (gen_ashrsi3 (temp, gen_rtx_SUBREG (SImode, operands[1], 0),
GEN_INT (35)));
/*emit_move_insn (operands[0], operands[1]);
emit_insn (gen_xorsi3 (op0hi, op0hi, temp));
emit_insn (gen_xorsi3 (op0lo, op0lo, temp));*/
emit_insn (gen_xordisi3 (operands[0], operands[1], temp));
emit_insn (gen_lshrdi3 (operands[0], operands[0], operands[2]));
/*emit_insn (gen_xorsi3 (op0hi, op0hi, temp));
emit_insn (gen_xorsi3 (op0lo, op0lo, temp));*/
emit_insn (gen_xordisi3 (operands[0], operands[0], temp));
DONE;
}
else if (GET_CODE (operands[2]) == CONST_INT)
{
emit_insn (gen_ASHC_right (operands[0], operands[1],
GEN_INT (-INTVAL (operands[2]))));
DONE;
}
else
operands[3] = gen_reg_rtx (SImode);")
(define_insn "ashrdi3_36"
[(set (match_operand:DI 0 "register_operand" "=r")
(ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
(const_int 36)))]
"!TARGET_71BIT"
"@
move %Z0,%0\;ash %0,-43"
[(set_attr "length" "2")])
(define_insn "sign_extension_di"
[(set (match_operand:DI 0 "register_operand" "=r,r")
(ashiftrt:DI (match_operand:DI 1 "register_operand" "0,r")
(const_int 71)))]
"!TARGET_71BIT"
{
if (which_alternative == 0)
return "ash %0,-43\;move %Z0,%0";
else if (REGNO (operands[0]) + 1 == REGNO (operands[1]))
return "ash %Z0,-43\;move %0,%Z0";
else
return "move %0,%1\;ash %0,-43\;move %Z0,%0";
}
[(set_attr "length" "2,3")])
(define_insn "ASHC_right"
[(set (match_operand:DI 0 "register_operand" "=r,r,r")
(ashiftrt:DI (match_operand:DI 1 "register_operand" "0,0,0")
(neg:SI (match_operand:SI 2 "general_operand" "x,K,m"))))]
"TARGET_71BIT"
"@
ashc %0,(%2)
ashc %0,%2
ashc %0,@%2")
(define_insn "ASHC"
[(set (match_operand:DI 0 "register_operand" "=r")
(unspec:DI [(match_operand:DI 1 "register_operand" "0")
(match_operand:SI 2 "const_int_operand" "K")]
UNSPEC_ASHC))]
"!TARGET_71BIT"
"ashc %0,%2")
(define_insn "*ASHC_right_plus"
[(set (match_operand:DI 0 "register_operand" "=r")
(ashiftrt:DI
(match_operand:DI 1 "register_operand" "0")
(neg:SI (plus:SI (match_operand:SI 2 "register_operand" "x")
(match_operand:SI 3 "immediate_operand" "K")))))]
"TARGET_71BIT"
"ashc %0,%3(%2)")
(define_insn "rotlsi3"
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
(rotate:SI (match_operand:SI 1 "register_operand" "0,0,0")
(match_operand:SI 2 "general_operand" "x,K,m")))]
""
"@
rot %0,(%2)
rot %0,%Y2
rot %0,@%2")
(define_insn "*ROT_left_plus"
[(set (match_operand:SI 0 "register_operand" "=r")
(rotate:SI (match_operand:SI 1 "register_operand" "0")
(plus:SI (match_operand:SI 2 "register_operand" "x")
(match_operand:SI 3 "immediate_operand" "K"))))]
""
"rot %0,%Y3(%2)")
(define_expand "rotrsi3"
[(set (match_dup 3) (neg:SI (match_operand:SI 2 "general_operand" "")))
(set (match_operand:SI 0 "register_operand" "")
(rotatert:SI (match_operand:SI 1 "register_operand" "")
(neg:SI (match_dup 3))))]
""
"operands[3] = gen_reg_rtx (SImode);")
(define_insn "*ROT_right"
[(set (match_operand:SI 0 "register_operand" "=r,r,r")
(rotatert:SI (match_operand:SI 1 "register_operand" "0,0,0")
(neg:SI (match_operand:SI 2 "general_operand" "x,K,m"))))]
""
"@
rot %0,(%2)
rot %0,%Y2
rot %0,@%2")
(define_insn "*ROT_right_plus"
[(set (match_operand:SI 0 "register_operand" "=r")
(rotatert:SI
(match_operand:SI 1 "register_operand" "0")
(neg:SI (plus:SI (match_operand:SI 2 "register_operand" "x")
(match_operand:SI 3 "immediate_operand" "K")))))]
""
"rot %0,%Y3(%2)")
(define_insn "rotldi3"
[(set (match_operand:DI 0 "register_operand" "=r,r,r")
(rotate:DI (match_operand:DI 1 "register_operand" "0,0,0")
(match_operand:SI 2 "general_operand" "x,K,m")))]
"!TARGET_71BIT"
"@
rotc %0,(%2)
rotc %0,%V2
rotc %0,@%2")
(define_insn "*ROTC_left_plus"
[(set (match_operand:DI 0 "register_operand" "=r")
(rotate:DI (match_operand:DI 1 "register_operand" "0")
(plus:SI (match_operand:SI 2 "register_operand" "x")
(match_operand:SI 3 "immediate_operand" "K"))))]
"!TARGET_71BIT"
"rotc %0,%V3(%2)")
(define_expand "rotrdi3"
[(set (match_dup 3) (neg:SI (match_operand:SI 2 "general_operand" "")))
(set (match_operand:DI 0 "register_operand" "")
(rotatert:DI (match_operand:DI 1 "register_operand" "")
(neg:SI (match_dup 3))))]
"!TARGET_71BIT"
"operands[3] = gen_reg_rtx (SImode);")
(define_insn "*ROTC_right"
[(set (match_operand:DI 0 "register_operand" "=r,r,r")
(rotatert:DI (match_operand:DI 1 "register_operand" "0,0,0")
(neg:SI (match_operand:SI 2 "general_operand" "x,K,m"))))]
"!TARGET_71BIT"
"@
rotc %0,(%2)
rotc %0,%V2
rotc %0,@%2")
(define_insn "*ROTC_right_plus"
[(set (match_operand:DI 0 "register_operand" "=r")
(rotatert:DI
(match_operand:DI 1 "register_operand" "0")
(neg:SI (plus:SI (match_operand:SI 2 "register_operand" "x")
(match_operand:SI 3 "immediate_operand" "K")))))]
"!TARGET_71BIT"
"rotc %0,%V3(%2)")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Logical Operations
;; SETZ -- in Data Movement
;; AND -- andsi3
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(and:SI (subreg:SI (match_operand:QI 1 "memory_operand" "m") 0)
(const_int 63)))]
""
"*return pdp10_output_extzv_foo (insn, operands);")
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(and:SI (match_operand:SI 1 "memory_operand" "m")
(match_operand:SI 2 "const_int_operand" "i")))]
"TARGET_LARGE && CONSTANT_ADDRESS_P (XEXP (operands[1], 0))
&& (INTVAL (operands[2]) == 077 || INTVAL (operands[2]) == 0777)"
{
rtx ops[4];
int bitsize = exact_log2 (INTVAL (operands[2]) + 1);
ops[0] = operands[0];
ops[1] = operands[1];
ops[2] = GEN_INT (bitsize);
ops[3] = GEN_INT (BITS_PER_WORD - bitsize);
output_asm_insn (pdp10_output_extzv (insn, ops), ops);
return "";
})
(define_expand "andsi3"
[(set (match_operand:SI 0 "reg_or_mem_operand" "")
(and:SI (match_operand:SI 1 "reg_or_mem_operand" "")
(match_operand:SI 2 "general_operand" "")))]
""
"")
(define_insn "*andsi3"
[(set (match_operand:SI 0 "reg_or_mem_operand" "=r,r,r,r,r,m")
(and:SI (match_operand:SI 1 "reg_or_mem_operand" "%0,0,0,0,0,0")
(match_operand:SI 2 "general_operand" "rm,I,N,P,i,r")))]
""
"@
and %0,%2
andi %0,%2
tlz %0,%T2
andcmi %0,%C2
and %0,[%2]
andm %2,%0")
(define_insn "*ANDI_reg"
[(set (match_operand:SI 0 "register_operand" "=r")
(and:SI (and:SI (match_operand:SI 1 "register_operand" "x")
(const_int RIGHT_HALF))
(match_operand:SI 2 "register_operand" "0")))]
""
"andi %0,(%1)")
(define_insn "*ANDI_const_plus_reg"
[(set (match_operand:SI 0 "register_operand" "=r")
(and:SI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "x")
(match_operand:SI 2 "const_int_operand" "I"))
(const_int RIGHT_HALF))
(match_operand:SI 3 "register_operand" "0")))]
"pdp10_const_ok_for_letter_p (INTVAL (operands[2]), 'I')"
"andi %0,%2(%1)")
(define_insn "*TLZ_reg"
[(set (match_operand:SI 0 "register_operand" "=r")
(and:SI (not:SI (ashift:SI (match_operand:SI 1 "register_operand" "x")
(const_int 18)))
(match_operand:SI 2 "register_operand" "0")))]
""
"tlz %0,(%1)")
(define_insn "*TLZ_const_plus_reg"
[(set (match_operand:SI 0 "register_operand" "=r")
(and:SI (not:SI (plus:SI (mult:SI
(match_operand:SI 1 "register_operand" "x")
(const_int 262144))
(match_operand:SI 2 "const_int_operand" "L")))
(match_operand:SI 3 "register_operand" "0")))]
"pdp10_const_ok_for_letter_p (INTVAL (operands[2]), 'L')"
"tlz %0,%S2(%1)")
(define_insn "*ANDB1"
[(set (match_operand:SI 0 "memory_operand" "+m")
(and:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
(set (match_operand:SI 2 "register_operand" "=1")
(and:SI (match_dup 0) (match_dup 1)))]
""
"andb %1,%0")
(define_insn "*ANDB2"
[(set (match_operand:SI 0 "memory_operand" "+m")
(and:SI (match_operand:SI 1 "register_operand" "r") (match_dup 0)))
(set (match_operand:SI 2 "register_operand" "=1")
(and:SI (match_dup 1) (match_dup 0)))]
""
"andb %1,%0")
;; ANDCA, ANDCM
(define_insn "ANDCx"
[(set (match_operand:SI 0 "reg_or_mem_operand" "=r,r,r,r,m,m")
(and:SI
(not:SI (match_operand:SI 1 "reg_or_mem_operand" "0,rm,0,0,r,0"))
(match_operand:SI 2 "general_operand" "rm,0,I,P,0,r")))]
""
"@
andca %0,%2
andcm %0,%1
andcai %0,%2
andcbi %0,%C2
andcam %1,%0
andcmm %2,%0")
(define_insn "*ANDCMI_reg"
[(set (match_operand:SI 0 "register_operand" "=r")
(and:SI (ior:SI (not:SI (match_operand:SI 1 "register_operand" "x"))
(const_int LEFT_HALF))
(match_operand:SI 2 "register_operand" "0")))]
""
"andcmi %0,(%1)")
(define_insn "*ANDCMI_const_plus_reg"
[(set (match_operand:SI 0 "register_operand" "=r")
(and:SI (ior:SI (not:SI
(plus:SI
(match_operand:SI 1 "register_operand" "x")
(match_operand:SI 2 "const_int_operand" "I")))
(const_int LEFT_HALF))
(match_operand:SI 3 "register_operand" "0")))]
"pdp10_const_ok_for_letter_p (INTVAL (operands[2]), 'I')"
"andcmi %0,%2(%1)")
(define_insn "*ANDCAB"
[(set (match_operand:SI 0 "memory_operand" "+m")
(and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
(match_dup 0)))
(set (match_operand:SI 2 "register_operand" "=1")
(and:SI (not:SI (match_dup 1)) (match_dup 0)))]
""
"andcab %1,%0")
(define_insn "*ANDCMB"
[(set (match_operand:SI 0 "memory_operand" "+m")
(and:SI (not:SI (match_dup 0))
(match_operand:SI 1 "register_operand" "r")))
(set (match_operand:SI 2 "register_operand" "=1")
(and:SI (not:SI (match_dup 0)) (match_dup 1)))]
""
"andcmb %1,%0")
; (define_insn "*ANDCMB"
; [(set (match_operand:SI 0 "register_operand" "=r")
; (and:SI (not:SI (match_operand:SI 1 "memory_operand" "+m"))
; (match_operand:SI 2 "register_operand" "0")))
; (set (match_dup 1)
; (and:SI (not:SI (match_dup 1)) (match_dup 2)))]
; ""
; "andcmb %0,%1")
;; SETM -- not useful
;; SETA -- not useful
;; XOR -- xorsi3
(define_insn "xorsi3"
[(set (match_operand:SI 0 "reg_or_mem_operand" "=r,r,r,r,r,m")
(xor:SI (match_operand:SI 1 "reg_or_mem_operand" "%0,0,0,0,0,0")
(match_operand:SI 2 "general_operand" "rm,I,L,P,i,r")))]
""
"@
xor %0,%2
xori %0,%2
tlc %0,%S2
eqvi %0,%C2
xor %0,[%2]
xorm %2,%0")
(define_insn "*XORI_reg"
[(set (match_operand:SI 0 "register_operand" "=r")
(xor:SI (and:SI (match_operand:SI 1 "register_operand" "r")
(const_int RIGHT_HALF))
(match_operand:SI 2 "register_operand" "0")))]
""
"xori %0,(%1)")
(define_insn "*XORI_const_plus_reg"
[(set (match_operand:SI 0 "register_operand" "=r")
(xor:SI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "const_int_operand" "I"))
(const_int RIGHT_HALF))
(match_operand:SI 3 "register_operand" "0")))]
"pdp10_const_ok_for_letter_p (INTVAL (operands[2]), 'I')"
"xori %0,%2(%1)")
(define_insn "*TLC_reg"
[(set (match_operand:SI 0 "register_operand" "=r")
(xor:SI (ashift:SI (match_operand:SI 1 "register_operand" "r")
(const_int 18))
(match_operand:SI 2 "register_operand" "0")))]
""
"tlc %0,(%1)")
(define_insn "*TLC_const_plus_reg"
[(set (match_operand:SI 0 "register_operand" "=r")
(xor:SI (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "x")
(const_int 262144))
(match_operand:SI 2 "const_int_operand" "L"))
(match_operand:SI 3 "register_operand" "0")))]
"pdp10_const_ok_for_letter_p (INTVAL (operands[2]), 'L')"
"tlc %0,%S2(%1)")
(define_insn "*XORB1"
[(set (match_operand:SI 0 "memory_operand" "+m")
(xor:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
(set (match_operand:SI 2 "register_operand" "=1")
(xor:SI (match_dup 0) (match_dup 1)))]
""
"xorb %1,%0")
(define_insn "*XORB2"
[(set (match_operand:SI 0 "memory_operand" "+m")
(xor:SI (match_operand:SI 1 "register_operand" "r") (match_dup 0)))
(set (match_operand:SI 2 "register_operand" "=1")
(xor:SI (match_dup 1) (match_dup 0)))]
""
"xorb %1,%0")
(define_insn "xordisi3"
[(set (match_operand:DI 0 "register_operand" "=r")
(xor:DI (match_operand:DI 1 "register_operand" "%0")
(plus:DI
(ashift:DI
(zero_extend:DI (match_operand:SI 2 "register_operand" "r"))
(const_int 36))
(zero_extend:DI (match_dup 2)))))]
""
"xor %0,%2\;xor %Z0,%2")
;; IOR -- iorsi3
(define_insn "iorsi3"
[(set (match_operand:SI 0 "reg_or_mem_operand" "=r,r,r,r,r,m")
(ior:SI (match_operand:SI 1 "reg_or_mem_operand" "%0,0,0,0,0,0")
(match_operand:SI 2 "general_operand" "rm,I,L,P,i,r")))]
""
"@
ior %0,%2
iori %0,%2
tlo %0,%S2
orcmi %0,%C2
ior %0,[%2]
iorm %2,%0")
(define_insn "*IORI_reg"
[(set (match_operand:SI 0 "register_operand" "=r")
(ior:SI (and:SI (match_operand:SI 1 "register_operand" "x")
(const_int RIGHT_HALF))
(match_operand:SI 2 "register_operand" "0")))]
""
"iori %0,(%1)")
(define_insn "*IORI_const_plus_reg"
[(set (match_operand:SI 0 "register_operand" "=r")
(ior:SI (and:SI (plus:SI (match_operand:SI 1 "register_operand" "x")
(match_operand:SI 2 "const_int_operand" "I"))
(const_int RIGHT_HALF))
(match_operand:SI 3 "register_operand" "0")))]
"pdp10_const_ok_for_letter_p (INTVAL (operands[2]), 'I')"
"iori %0,%2(%1)")
(define_insn "*TLO_reg"
[(set (match_operand:SI 0 "register_operand" "=r")
(ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "x")
(const_int 18))
(match_operand:SI 2 "register_operand" "0")))]
""
"tlo %0,(%1)")
(define_insn "*TLO_const_plus_reg"
[(set (match_operand:SI 0 "register_operand" "=r")
(ior:SI (plus:SI (mult:SI (match_operand:SI 1 "register_operand" "x")
(const_int 262144))
(match_operand:SI 2 "const_int_operand" "L"))
(match_operand:SI 3 "register_operand" "0")))]
"pdp10_const_ok_for_letter_p (INTVAL (operands[2]), 'L')"
"tlo %0,%S2(%1)")
(define_insn "*IORB1"
[(set (match_operand:SI 0 "memory_operand" "+m")
(ior:SI (match_dup 0) (match_operand:SI 1 "register_operand" "r")))
(set (match_operand:SI 2 "register_operand" "=1")
(ior:SI (match_dup 0) (match_dup 1)))]
""
"iorb %1,%0")
(define_insn "*IORB2"
[(set (match_operand:SI 0 "memory_operand" "+m")
(ior:SI (match_operand:SI 1 "register_operand" "r") (match_dup 0)))
(set (match_operand:SI 2 "register_operand" "=1")
(ior:SI (match_dup 1) (match_dup 0)))]
""
"iorb %1,%0")
;; ANDCB
(define_insn "*ANCDB"
[(set (match_operand:SI 0 "reg_or_mem_operand" "=r,m")
(and:SI (not:SI (match_operand:SI 1 "reg_or_mem_operand" "%0,0"))
(not:SI (match_operand:SI 2 "reg_or_mem_operand" "rm,r"))))]
""
"@
andcb %0,%2
andcbm %2,%0")
(define_insn "*ANDCBI_reg"
[(set (match_operand:SI 0 "register_operand" "=r")
(and:SI (not:SI (and:SI (match_operand:SI 1 "register_operand" "x")
(const_int RIGHT_HALF)))
(not:SI (match_operand:SI 2 "register_operand" "0"))))]
""
"andcbi %0,(%1)")
(define_insn "*ANDCBI_const_plus_reg"
[(set (match_operand:SI 0 "register_operand" "=r")
(and:SI (not:SI (and:SI
(plus:SI
(match_operand:SI 2 "register_operand" "x")
(match_operand:SI 3 "const_int_operand" "I"))
(const_int RIGHT_HALF)))
(not:SI (match_operand:SI 1 "register_operand" "0"))))]
"pdp10_const_ok_for_letter_p (INTVAL (operands[3]), 'I')"
"andcbi %0,%3(%2)")
(define_insn "*ANDCBB1"
[(set (match_operand:SI 0 "memory_operand" "+m")
(and:SI (not:SI (match_dup 0))
(not:SI (match_operand:SI 1 "register_operand" "r"))))
(set (match_operand:SI 2 "register_operand" "=1")
(and:SI (not:SI (match_dup 0)) (not:SI (match_dup 1))))]
""
"andcbb %1,%0")
(define_insn "*ANDCBB2"
[(set (match_operand:SI 0 "memory_operand" "+m")
(and:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
(not:SI (match_dup 0))))
(set (match_operand:SI 2 "register_operand" "=1")
(and:SI (not:SI (match_dup 1)) (not:SI (match_dup 0))))]
""
"andcbb %1,%0")
(define_insn "*ANDCBB"
[(set (match_operand:SI 0 "register_operand" "=r")
(and:SI (not:SI (match_operand:SI 1 "register_operand" "%0"))
(not:SI (match_operand:SI 2 "memory_operand" "+m"))))
(set (match_dup 2)
(and:SI (not:SI (match_dup 1)) (not:SI (match_dup 2))))]
""
"andcbb %0,%2")
;; EQV
(define_insn "*EQV"
[(set (match_operand:SI 0 "reg_or_mem_operand" "=r,m")
(not:SI (xor:SI (match_operand:SI 1 "reg_or_mem_operand" "%0,0")
(match_operand:SI 2 "reg_or_mem_operand" "rm,r"))))]
""
"@
eqv %0,%2
eqvm %2,%0")
(define_insn "*EQVI_reg"
[(set (match_operand:SI 0 "register_operand" "=r")
(not:SI (xor:SI (and:SI (match_operand:SI 1 "register_operand" "x")
(const_int RIGHT_HALF))
(match_operand:SI 2 "register_operand" "0"))))]
""
"eqvi %0,(%1)")
(define_insn "*EQVI_const_plus_reg"
[(set (match_operand:SI 0 "register_operand" "=r")
(not:SI (xor:SI (and:SI (plus:SI
(match_operand:SI 1 "register_operand" "x")
(match_operand:SI 2 "const_int_operand" "I"))
(const_int RIGHT_HALF))
(match_operand:SI 3 "register_operand" "0"))))]
"pdp10_const_ok_for_letter_p (INTVAL (operands[2]), 'I')"
"eqvi %0,%2(%1)")
(define_insn "*EQVB1"
[(set (match_operand:SI 0 "memory_operand" "+m")
(not:SI (xor:SI (match_dup 0)
(match_operand:SI 1 "register_operand" "r"))))
(set (match_operand:SI 2 "register_operand" "=1")
(not:SI (xor:SI (match_dup 0) (match_dup 1))))]
""
"eqvb %1,%0")
(define_insn "*EQVB2"
[(set (match_operand:SI 0 "memory_operand" "+m")
(not:SI (xor:SI (match_operand:SI 1 "register_operand" "r")
(match_dup 0))))
(set (match_operand:SI 2 "register_operand" "=1")
(not:SI (xor:SI (match_dup 1) (match_dup 0))))]
""
"eqvb %1,%0")
;; SETCA, SETCM -- one_cmplsi2
(define_insn "one_cmplsi2"
[(set (match_operand:SI 0 "reg_or_mem_operand" "=r,r,m,m")
(not:SI (match_operand:SI 1 "reg_or_mem_operand" "0,rm,r,0")))]
""
"@
setca %0,
setcm %0,%1
setcam %1,%0
setcmm %0")
(define_insn "*SETCAB"
[(set (match_operand:SI 0 "memory_operand" "+m")
(not:SI (match_operand:SI 1 "register_operand" "r")))
(set (match_operand:SI 2 "register_operand" "=1")
(not:SI (match_dup 1)))]
""
"setcab %1,%0")
(define_insn "*SETCMB"
[(set (match_operand:SI 0 "memory_operand" "+m")
(not:SI (match_dup 0)))
(set (match_operand:SI 1 "register_operand" "=r")
(not:SI (match_dup 0)))]
""
"setcmb %0,%1")
;; SETCMI is done with ORCBI.
;; ORCA, ORCM
(define_insn "*ORCx"
[(set (match_operand:SI 0 "reg_or_mem_operand" "=r,r,r,r,m,m")
(ior:SI
(not:SI (match_operand:SI 1 "reg_or_mem_operand" "0,rm,0,0,r,0"))
(match_operand:SI 2 "general_operand" "rm,0,I,P,0,r")))]
""
"@
orca %0,%2
orcm %0,%1
orcai %0,%2
orcbi %0,%C2
orcam %1,%0
orcmm %2,%0")
(define_insn "*ORCMI_reg"
[(set (match_operand:SI 0 "register_operand" "=r")
(ior:SI (ior:SI (not:SI (match_operand:SI 1 "register_operand" "x"))
(const_int LEFT_HALF))
(match_operand:SI 2 "register_operand" "0")))]
""
"orcmi %0,(%1)")
(define_insn "*ORCMI_const_plus_reg"
[(set (match_operand:SI 0 "register_operand" "=r")
(ior:SI (ior:SI (not:SI (plus:SI
(match_operand:SI 1 "register_operand" "x")
(match_operand:SI 2 "const_int_operand" "I")))
(const_int LEFT_HALF))
(match_operand:SI 3 "register_operand" "0")))]
"pdp10_const_ok_for_letter_p (INTVAL (operands[2]), 'I')"
"orcmi %0,%2(%1)")
(define_insn "*ORCAB1"
[(set (match_operand:SI 0 "memory_operand" "+m")
(ior:SI (match_dup 0)
(not:SI (match_operand:SI 1 "register_operand" "r"))))
(set (match_operand:SI 2 "register_operand" "=1")
(ior:SI (match_dup 0) (not:SI (match_dup 1))))]
""
"orcab %1,%0")
(define_insn "*ORCAB2"
[(set (match_operand:SI 0 "memory_operand" "+m")
(ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
(match_dup 0)))
(set (match_operand:SI 2 "register_operand" "=1")
(ior:SI (not:SI (match_dup 1)) (match_dup 0)))]
""
"orcab %1,%0")
(define_insn "*ORCMB1"
[(set (match_operand:SI 0 "memory_operand" "+m")
(ior:SI (not:SI (match_dup 0))
(match_operand:SI 1 "register_operand" "r")))
(set (match_operand:SI 2 "register_operand" "=1")
(ior:SI (not:SI (match_dup 0)) (match_dup 1)))]
""
"orcmb %1,%0")
(define_insn "*ORCMB2"
[(set (match_operand:SI 0 "memory_operand" "+m")
(ior:SI (match_operand:SI 1 "register_operand" "r")
(not:SI (match_dup 0))))
(set (match_operand:SI 2 "register_operand" "=1")
(ior:SI (match_dup 1) (not:SI (match_dup 0))))]
""
"orcmb %1,%0")
;; ORCB
(define_insn "*ORCB"
[(set (match_operand:SI 0 "reg_or_mem_operand" "=r,m")
(ior:SI (not:SI (match_operand:SI 1 "reg_or_mem_operand" "%0,0"))
(not:SI (match_operand:SI 2 "reg_or_mem_operand" "rm,r"))))]
""
"@
orcb %0,%2
orcbm %2,%0")
(define_insn "*ORCBI_reg"
[(set (match_operand:SI 0 "register_operand" "=r")
(ior:SI (not:SI (and:SI (match_operand:SI 1 "register_operand" "x")
(const_int RIGHT_HALF)))
(not:SI (match_operand:SI 2 "register_operand" "0"))))]
""
"orcbi %0,(%1)")
(define_insn "*ORCBI_const_plus_reg"
[(set (match_operand:SI 0 "register_operand" "=r")
(ior:SI (not:SI (and:SI (plus:SI
(match_operand:SI 1 "register_operand" "x")
(match_operand:SI 2 "const_int_operand" "I"))
(const_int RIGHT_HALF)))
(not:SI (match_operand:SI 3 "register_operand" "0"))))]
""
"orcbi %0,%2(%1)")
(define_insn "*ORCMB1"
[(set (match_operand:SI 0 "memory_operand" "+m")
(ior:SI (not:SI (match_dup 0))
(not:SI (match_operand:SI 1 "register_operand" "r"))))
(set (match_operand:SI 2 "register_operand" "=1")
(ior:SI (not:SI (match_dup 0)) (not:SI (match_dup 1))))]
""
"orcbb %1,%0")
(define_insn "*ORCMB2"
[(set (match_operand:SI 0 "memory_operand" "+m")
(ior:SI (not:SI (match_operand:SI 1 "register_operand" "r"))
(not:SI (match_dup 0))))
(set (match_operand:SI 2 "register_operand" "=1")
(ior:SI (not:SI (match_dup 1)) (not:SI (match_dup 0))))]
""
"orcbb %1,%0")
;; SETO -- in Data Movement
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Floating-point Arithmetic
(define_insn "addsf3"
[(set (match_operand:SF 0 "reg_or_mem_operand" "=r,r,r,m")
(plus:SF (match_operand:SF 1 "reg_or_mem_operand" "%0,0,0,0")
(match_operand:SF 2 "general_operand" "rm,G,F,r")))]
""
"@
fadr %0,%2
fadri %0,%G2
fadr %0,[%2]
fadrm %2,%0")
(define_insn "*FADRB1"
[(set (match_operand:SF 0 "memory_operand" "+m")
(plus:SF (match_dup 0) (match_operand:SF 1 "register_operand" "r")))
(set (match_operand:SF 2 "register_operand" "=1")
(plus:SF (match_dup 0) (match_dup 1)))]
""
"fadrb %1,%0")
(define_insn "*FADRB2"
[(set (match_operand:SF 0 "memory_operand" "+m")
(plus:SF (match_operand:SF 1 "register_operand" "r") (match_dup 0)))
(set (match_operand:SF 2 "register_operand" "=1")
(plus:SF (match_dup 1) (match_dup 0)))]
""
"fadrb %1,%0")
(define_expand "adddf3"
[(set (match_operand:DF 0 "register_operand" "")
(plus:DF (match_operand:DF 1 "register_operand" "")
(match_operand:DF 2 "general_operand" "")))]
"(TARGET_KI10up && !TARGET_GFLOAT) || (TARGET_KL10up && TARGET_GFLOAT)"
"")
(define_insn "DFAD"
[(set (match_operand:DF 0 "register_operand" "=r,r")
(plus:DF (match_operand:DF 1 "register_operand" "%0,0")
(match_operand:DF 2 "general_operand" "rm,F")))]
"TARGET_KI10up && !TARGET_GFLOAT"
"@
dfad %0,%2
dfad %0,[%2]")
(define_insn "*GFAD"
[(set (match_operand:DF 0 "register_operand" "=r,r")
(plus:DF (match_operand:DF 1 "register_operand" "%0,0")
(match_operand:DF 2 "general_operand" "rm,F")))]
"TARGET_KL10up && TARGET_GFLOAT"
"@
gfad %0,%2
gfad %0,[%2]")
(define_insn "subsf3"
[(set (match_operand:SF 0 "reg_or_mem_operand" "=r,r,r,m")
(minus:SF (match_operand:SF 1 "register_operand" "0,0,0,r")
(match_operand:SF 2 "general_operand" "rm,G,F,0")))]
""
"@
fsbr %0,%2
fsbri %0,%G2
fsbr %0,[%2]
fsbrm %1,%0")
(define_insn "*FSBRB"
[(set (match_operand:SF 0 "memory_operand" "+m")
(minus:SF (match_operand:SF 1 "register_operand" "r") (match_dup 0)))
(set (match_operand:SF 2 "register_operand" "=1")
(minus:SF (match_dup 1) (match_dup 0)))]
""
"fsbrb %1,%0")
(define_expand "subdf3"
[(set (match_operand:DF 0 "register_operand" "")
(minus:DF (match_operand:DF 1 "register_operand" "")
(match_operand:DF 2 "general_operand" "")))]
"TARGET_KI10up"
"")
(define_insn "*DFSB"
[(set (match_operand:DF 0 "register_operand" "=r,r")
(minus:DF (match_operand:DF 1 "register_operand" "0,0")
(match_operand:DF 2 "general_operand" "rm,F")))]
"TARGET_KI10up && !TARGET_GFLOAT"
"@
dfsb %0,%2
dfsb %0,[%2]")
(define_insn "*GFSB"
[(set (match_operand:DF 0 "register_operand" "=r,r")
(minus:DF (match_operand:DF 1 "register_operand" "0,0")
(match_operand:DF 2 "general_operand" "rm,F")))]
"TARGET_KL10up && TARGET_GFLOAT"
"@
gfsb %0,%2
gfsb %0,[%2]")
(define_insn "abssf2"
[(set (match_operand:SF 0 "reg_or_mem_operand" "=r,m,m")
(abs:SF (match_operand:SF 1 "reg_or_mem_operand" "rm,r,0")))]
""
"@
movm %0,%1
movmm %1,%0
movms %0")
(define_insn "*MOVMSsf"
[(set (match_operand:SF 0 "reg_or_mem_operand" "+rm")
(abs:SF (match_dup 0)))
(set (match_operand:SF 1 "register_operand" "=x")
(abs:SF (match_dup 0)))]
""
"movms %1,%0")
(define_insn "negsf2"
[(set (match_operand:SF 0 "reg_or_mem_operand" "=r,m,m")
(neg:SF (match_operand:SF 1 "reg_or_mem_operand" "rm,r,0")))]
""
"@
movn %0,%1
movnm %1,%0
movns %0")
(define_insn "*MOVNS"
[(set (match_operand:SF 0 "reg_or_mem_operand" "=rm")
(neg:SF (match_dup 0)))
(set (match_operand:SF 1 "register_operand" "+x")
(neg:SF (match_dup 0)))]
""
"movns %1,%0")
(define_insn "negdf2"
[(set (match_operand:DF 0 "reg_or_mem_operand" "=r,m")
(neg:DF (match_operand:DF 1 "reg_or_mem_operand" "rm,r")))]
"TARGET_KI10up"
"@
dmovn %0,%1
dmovnm %1,%0")
(define_insn "mulsf3"
[(set (match_operand:SF 0 "reg_or_mem_operand" "=r,r,r,m")
(mult:SF (match_operand:SF 1 "reg_or_mem_operand" "%0,0,0,0")
(match_operand:SF 2 "general_operand" "rm,G,F,r")))]
""
"@
fmpr %0,%2
fmpri %0,%G2
fmpr %0,[%2]
fmprm %2,%0")
(define_insn "*FMPRB1"
[(set (match_operand:SF 0 "memory_operand" "+m")
(mult:SF (match_dup 0) (match_operand:SF 1 "register_operand" "r")))
(set (match_operand:SF 2 "register_operand" "=1")
(mult:SF (match_dup 0) (match_dup 1)))]
""
"fmprb %1,%0")
(define_insn "*FMPRB2"
[(set (match_operand:SF 0 "memory_operand" "+m")
(mult:SF (match_operand:SF 1 "register_operand" "r") (match_dup 0)))
(set (match_operand:SF 2 "register_operand" "=1")
(mult:SF (match_dup 1) (match_dup 0)))]
""
"fmprb %1,%0")
(define_expand "muldf3"
[(set (match_operand:DF 0 "register_operand" "")
(mult:DF (match_operand:DF 1 "register_operand" "")
(match_operand:DF 2 "general_operand" "")))]
"TARGET_KI10up"
"")
(define_insn "*DFMP"
[(set (match_operand:DF 0 "register_operand" "=r,r")
(mult:DF (match_operand:DF 1 "register_operand" "%0,0")
(match_operand:DF 2 "general_operand" "rm,F")))]
"TARGET_KI10up && !TARGET_GFLOAT"
"@
dfmp %0,%2
dfmp %0,[%2]")
(define_insn "*GFMP"
[(set (match_operand:DF 0 "register_operand" "=r,r")
(mult:DF (match_operand:DF 1 "register_operand" "%0,0")
(match_operand:DF 2 "general_operand" "rm,F")))]
"TARGET_KL10up && TARGET_GFLOAT"
"@
gfmp %0,%2
gfmp %0,[%2]")
(define_insn "divsf3"
[(set (match_operand:SF 0 "reg_or_mem_operand" "=r,r,r,m")
(div:SF (match_operand:SF 1 "register_operand" "0,0,0,r")
(match_operand:SF 2 "general_operand" "rm,G,F,0")))]
""
"@
fdvr %0,%2
fdvri %0,%G2
fdvr %0,[%2]
fdvrm %1,%0")
(define_insn "*FDVRB2"
[(set (match_operand:SF 0 "memory_operand" "+m")
(div:SF (match_operand:SF 1 "register_operand" "r") (match_dup 0)))
(set (match_operand:SF 2 "register_operand" "=1")
(div:SF (match_dup 1) (match_dup 0)))]
""
"fdvrb %1,%0")
(define_expand "divdf3"
[(set (match_operand:DF 0 "register_operand" "")
(div:DF (match_operand:DF 1 "register_operand" "")
(match_operand:DF 2 "general_operand" "")))]
"TARGET_KI10up"
"")
(define_insn "*DFDV"
[(set (match_operand:DF 0 "register_operand" "=r,r")
(div:DF (match_operand:DF 1 "register_operand" "0,0")
(match_operand:DF 2 "general_operand" "rm,F")))]
"TARGET_KI10up && !TARGET_GFLOAT"
"@
dfdv %0,%2
dfdv %0,[%2]")
(define_insn "*GFDV"
[(set (match_operand:DF 0 "register_operand" "=r,r")
(div:DF (match_operand:DF 1 "register_operand" "0,0")
(match_operand:DF 2 "general_operand" "rm,F")))]
"TARGET_KL10up && TARGET_GFLOAT"
"@
gfdv %0,%2
gfdv %0,[%2]")
(define_insn "sqrtsf2"
[(set (match_operand:SF 0 "register_operand" "=r")
(sqrt:SF (match_operand:SF 1 "reg_or_mem_operand" "rm")))]
"TARGET_XKL2"
"extend %0,[sqrt %1]")
(define_expand "sqrtdf2"
[(set (match_operand:DF 0 "register_operand" "")
(sqrt:DF (match_operand:DF 1 "reg_or_mem_operand" "")))]
"TARGET_XKL2"
"")
(define_insn "*DSQRT"
[(set (match_operand:DF 0 "register_operand" "=r")
(sqrt:DF (match_operand:DF 1 "reg_or_mem_operand" "rm")))]
"TARGET_XKL2 && !TARGET_GFLOAT"
"extend %0,[dsqrt %1]")
(define_insn "*GSQRT"
[(set (match_operand:DF 0 "register_operand" "=r")
(sqrt:DF (match_operand:DF 1 "reg_or_mem_operand" "rm")))]
"TARGET_XKL2 && TARGET_GFLOAT"
"extend %0,[gsqrt %1]")
(define_insn "FSC"
[(set (match_operand:SF 0 "register_operand" "=r,r")
(unspec:SF
[(match_operand:SF 1 "register_operand" "0,0")
(match_operand:SI 2 "nonmemory_operand" "K,x")]
UNSPEC_FSC))]
""
"@
fsc %0,%2
fsc %0,(%2)")
(define_expand "DFSC"
[(set (match_operand:DF 0 "register_operand" "=r,r")
(unspec:DF
[(match_operand:DF 1 "register_operand" "0,0")
(match_operand:SI 2 "nonmemory_operand" "K,r")]
UNSPEC_FSC))]
"!TARGET_GFLOAT"
"if (!TARGET_XKL2)
{
rtx x = gen_rtx_REG (SFmode, REGNO (operands[0]));
if (!flag_unsafe_math_optimizations)
emit_insn (gen_DFAD (operands[0], operands[1], CONST0_RTX (DFmode)));
emit_insn (gen_FSC (x, x, operands[2]));
DONE;
}")
(define_insn "*DFSC"
[(set (match_operand:DF 0 "register_operand" "=r,r")
(unspec:DF
[(match_operand:DF 1 "register_operand" "0,0")
(match_operand:SI 2 "nonmemory_operand" "K,x")]
UNSPEC_FSC))]
"TARGET_XKL2 && !TARGET_GFLOAT"
"@
extend %0,[dfsc %2]
extend %0,[dfsc (%2)]")
(define_insn "GFSC"
[(set (match_operand:DF 0 "register_operand" "=r,r")
(unspec:DF
[(match_operand:DF 1 "register_operand" "0,0")
(match_operand:SI 2 "nonmemory_operand" "K,x")]
UNSPEC_FSC))]
"TARGET_KL10up && TARGET_GFLOAT"
"@
extend %0,[gfsc %2]
extend %0,[gfsc (%2)]")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Floating-point Conversions
(define_expand "fix_truncsfsi2"
[(set (match_operand:SI 0 "register_operand" "")
(fix:SI (match_operand:SF 1 "reg_or_mem_operand" "")))]
""
"if (!TARGET_KI10up)
{
rtx temp = gen_reg_rtx (DImode);
rtx temp0 = gen_rtx_SUBREG (SImode, temp, 0);
rtx temp1 = gen_rtx_SUBREG (SImode, temp, 4);
/* Sequence taken from KCC. */
emit_insn (gen_MUL (temp,
gen_rtx_SUBREG (SImode, operands[1], 0),
GEN_INT (0400)));
emit_insn (gen_TSC (temp0, temp0));
/*emit_insn (gen_ashrsi3 (operands[0], temp1,
gen_rtx_PLUS (SImode, temp0, GEN_INT (-0243))));*/
emit_insn
(gen_rtx_SET
(VOIDmode,
operands[0],
gen_rtx_ASHIFTRT
(SImode,
temp0,
gen_rtx_NEG
(SImode,
gen_rtx_PLUS
(SImode,
temp1,
GEN_INT (-0243))))));
DONE;
}")
(define_insn "*fix_truncsfsi2"
[(set (match_operand:SI 0 "register_operand" "=r")
(fix:SI (match_operand:SF 1 "reg_or_mem_operand" "rm")))]
"TARGET_KI10up"
"fix %0,%1")
; (define_insn "fix_truncsfdi2" ...)
(define_expand "fix_truncdfsi2"
[(set (match_operand:SI 0 "register_operand" "")
(fix:SI (match_operand:DF 1 "reg_or_mem_operand" "")))]
"(TARGET_KL10up && TARGET_GFLOAT) || (TARGET_XKL2 && !TARGET_GFLOAT)"
"")
(define_insn "*DFIX"
[(set (match_operand:SI 0 "register_operand" "=r")
(fix:SI (match_operand:DF 1 "reg_or_mem_operand" "rm")))]
"TARGET_XKL2 && !TARGET_GFLOAT"
"extend %0,[dfix %1]")
(define_insn "*GFIX"
[(set (match_operand:SI 0 "register_operand" "=r")
(fix:SI (match_operand:DF 1 "reg_or_mem_operand" "rm")))]
"TARGET_KL10up && TARGET_GFLOAT"
"extend %0,[gfix %1]")
(define_expand "fix_truncdfdi2"
[(set (match_operand:DI 0 "register_operand" "")
(fix:DI (match_operand:DF 1 "reg_or_mem_operand" "")))]
"(TARGET_KL10up && TARGET_GFLOAT) || (TARGET_XKL2 && !TARGET_GFLOAT)"
"")
(define_insn "*DDFIX"
[(set (match_operand:DI 0 "register_operand" "=r")
(fix:DI (match_operand:DF 1 "reg_or_mem_operand" "rm")))]
"TARGET_XKL2 && !TARGET_GFLOAT"
"extend %0,[ddfix %1]")
(define_insn "*GDFIX"
[(set (match_operand:DI 0 "register_operand" "=r")
(fix:DI (match_operand:DF 1 "reg_or_mem_operand" "rm")))]
"TARGET_KL10up && TARGET_GFLOAT"
"extend %0,[gdfix %1]")
(define_insn "floatunsqisf2"
[(set (match_operand:SF 0 "register_operand" "=r")
(unsigned_float:SF (match_operand:QI 1 "register_operand" "0")))]
""
"fsc %0,233")
(define_insn "floatunshisf2"
[(set (match_operand:SF 0 "register_operand" "=r")
(unsigned_float:SF (match_operand:HI 1 "register_operand" "0")))]
""
"fsc %0,233")
(define_insn "floatsisf2"
[(set (match_operand:SF 0 "register_operand" "=r")
(float:SF (match_operand:SI 1 "reg_or_mem_operand" "rm")))]
"TARGET_KI10up"
"fltr %0,%1")
(define_insn "floatunssisf2"
[(set (match_operand:SF 0 "register_operand" "=r")
(unsigned_float:SF (match_operand:SI 1 "reg_or_mem_operand" "rm")))]
"TARGET_KI10up"
{
if (TARGET_XKL2)
return "ufltr %0,%1";
else
/* Sequence taken from KCC. */
return "skipge %0,%1\;%_lsh %0,1\;fltr %0,%0\;skipge %@%1\;%_fsc %0,1";
}
[(set (attr "length")
(if_then_else (ne (symbol_ref "TARGET_XKL2") (const_int 0))
(const_int 1)
(const_int 5)))])
; (define_insn "floatdisf2" ...)
(define_insn "floatunsqidf2"
[(set (match_operand:DF 0 "register_operand" "=r")
(unsigned_float:DF (match_operand:QI 1 "register_operand" "0")))]
"!TARGET_GFLOAT"
"fsc %0,233\;movei %Z0,0"
[(set_attr "length" "2")])
(define_insn "floatunshidf2"
[(set (match_operand:DF 0 "register_operand" "=r")
(unsigned_float:DF (match_operand:HI 1 "register_operand" "0")))]
"!TARGET_GFLOAT"
"fsc %0,233\;movei %Z0,0"
[(set_attr "length" "2")])
(define_expand "floatsidf2"
[(set (match_operand:DF 0 "register_operand" "")
(float:DF (match_operand:SI 1 "reg_or_mem_operand" "")))]
"TARGET_KL10up || (TARGET_KI10 && !TARGET_GFLOAT)"
"if (TARGET_KI10up && !TARGET_XKL2 && !TARGET_GFLOAT)
{
rtx temp = gen_rtx_SUBREG (DImode, operands[0], 0);
rtx temp0 = gen_rtx_SUBREG (SImode, operands[0], 0);
rtx temp1 = gen_rtx_SUBREG (SImode, operands[0], 4);
/* Sequence taken from KCC. */
emit_move_insn (temp0, operands[1]);
emit_move_insn (temp1, const0_rtx);
emit_insn (gen_ASHC_right (temp, temp, GEN_INT (8)));
emit_insn (gen_xorsi3 (temp0, temp0,
GEN_INT ((HOST_WIDE_INT)0243 << 27)));
if (!flag_unsafe_math_optimizations)
emit_insn (gen_adddf3 (operands[0], operands[0],
CONST0_RTX (DFmode)));
DONE;
}")
(define_insn "*DFLTR"
[(set (match_operand:DF 0 "register_operand" "=r")
(float:DF (match_operand:SI 1 "reg_or_mem_operand" "rm")))]
"TARGET_XKL2 && !TARGET_GFLOAT"
"extend %0,[dfltr %1]")
(define_insn "*GFLTR"
[(set (match_operand:DF 0 "register_operand" "=r")
(float:DF (match_operand:SI 1 "reg_or_mem_operand" "rm")))]
"TARGET_KL10up && TARGET_GFLOAT"
"extend %0,[gfltr %1]")
(define_expand "floatunssidf2"
[(set (match_operand:DF 0 "register_operand" "")
(unsigned_float:DF (match_operand:SI 1 "reg_or_mem_operand" "")))]
""
"if (!TARGET_XKL2)
{
rtx temp = gen_rtx_SUBREG (DImode, operands[0], 0);
rtx temp0 = gen_rtx_SUBREG (SImode, operands[0], 0);
rtx temp1 = gen_rtx_SUBREG (SImode, operands[0], 4);
/* Sequence taken from KCC. */
emit_move_insn (temp0, operands[1]);
emit_move_insn (temp1, const0_rtx);
emit_insn (gen_lshrdi3 (temp, temp, GEN_INT (9)));
emit_insn (gen_lshrsi3 (temp1, temp1, GEN_INT (1)));
emit_insn (gen_xorsi3 (temp0, temp0,
TARGET_GFLOAT
? GEN_INT ((HOST_WIDE_INT)02743 << 24)
: GEN_INT ((HOST_WIDE_INT)0243 << 27)));
if (!flag_unsafe_math_optimizations)
emit_insn (gen_adddf3 (operands[0], operands[0],
CONST0_RTX (DFmode)));
DONE;
}")
(define_insn "*UDFLTR"
[(set (match_operand:DF 0 "register_operand" "=r")
(unsigned_float:DF (match_operand:SI 1 "reg_or_mem_operand" "rm")))]
"TARGET_XKL2 && !TARGET_GFLOAT"
"extend %0,[udfltr %1]")
(define_insn "*UGFLTR"
[(set (match_operand:DF 0 "register_operand" "=r")
(unsigned_float:DF (match_operand:SI 1 "reg_or_mem_operand" "rm")))]
"TARGET_XKL2 && TARGET_GFLOAT"
"extend %0,[ugfltr %1]")
(define_expand "floatdidf2"
[(set (match_operand:DF 0 "register_operand" "")
(float:DF (match_operand:DI 1 "reg_or_mem_operand" "")))]
"(TARGET_KL10up && TARGET_GFLOAT) || (TARGET_XKL2 && !TARGET_GFLOAT)"
"")
(define_insn "*DDFLTR"
[(set (match_operand:DF 0 "register_operand" "=r")
(float:DF (match_operand:DI 1 "reg_or_mem_operand" "rm")))]
"TARGET_XKL2 && !TARGET_GFLOAT"
"extend %0,[ddfltr %1]")
(define_insn "*DGFLTR"
[(set (match_operand:DF 0 "register_operand" "=r")
(float:DF (match_operand:DI 1 "reg_or_mem_operand" "rm")))]
"TARGET_KL10up && TARGET_GFLOAT"
"extend %0,[dgfltr %1]")
(define_expand "extendsfdf2"
[(set (match_operand:DF 0 "reg_or_mem_operand" "")
(float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "")))]
"!TARGET_GFLOAT || TARGET_KL10up"
"")
;; Extend to D-float by moving the high-order word (if necessary) and
;; zeroing the low-order word.
(define_insn "*extendsfdf2"
[(set (match_operand:DF 0 "reg_or_mem_operand" "=r,o,r,o")
(float_extend:DF
(match_operand:SF 1 "reg_or_mem_operand" "0,0,rm,r")))]
"!TARGET_GFLOAT"
"@
movei %Z0,0%; extendsfdf2
setzm %Z0%; extendsfdf2
move %0,%1%; extendsfdf2\;movei %Z0,0%; extendsfdf2
movem %1,%0%; extendsfdf2\;setzm %Z0%; extendsfdf2"
[(set (attr "length")
(if_then_else (eq_attr "alternative" "0,1")
(const_int 1)
(const_int 2)))])
(define_insn "*GSNGL"
[(set (match_operand:DF 0 "register_operand" "=r")
(float_extend:DF (match_operand:SF 1 "reg_or_mem_operand" "rm")))]
"TARGET_KL10up && TARGET_GFLOAT"
"extend %0,[gsngl %1]")
(define_expand "truncdfsf2"
[(set (match_operand:SF 0 "reg_or_mem_operand" "")
(float_truncate:SF (match_operand:DF 1 "reg_or_mem_operand" "")))]
"!TARGET_GFLOAT || TARGET_KL10up"
"")
;; Truncate from D-float by just dropping the low-order word.
;; FIXME: this is not good enough, rounding needed. Or is it??
(define_insn "*truncdfsf2"
[(set (match_operand:SF 0 "reg_or_mem_operand" "=r,m,r,m")
(float_truncate:SF
(match_operand:DF 1 "reg_or_mem_operand" "0,0,rm,r")))]
"!TARGET_GFLOAT"
"@
\\t%; truncdfsf2
\\t%; truncdfsf2
move %0,%1%; truncdfsf2
movem %1,%0%; truncdfsf2"
[(set (attr "length")
(if_then_else (eq_attr "alternative" "0,1")
(const_int 0)
(const_int 1)))])
(define_insn "*GDBLE"
[(set (match_operand:SF 0 "register_operand" "=r")
(float_truncate:SF (match_operand:DF 1 "reg_or_mem_operand" "rm")))]
"TARGET_KL10up && TARGET_GFLOAT"
"extend %0,[gdble %1]")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Pointer Arithmetic
(define_insn "*ADJBP_0"
[(set (match_operand:SI 0 "reg_or_mem_operand" "=rm,r,m")
(unspec:SI
[(match_operand:SI 1 "reg_or_mem_operand" "0,rm,r")
(const_int 0)]
UNSPEC_ADJBP))]
""
"@
%; nothing
move %0,%1
movem %1,%0"
[(set_attr "length" "0,1,1")])
(define_insn "IBP"
[(set (match_operand:SI 0 "reg_or_mem_operand" "=rm")
(unspec:SI
[(match_operand:SI 1 "reg_or_mem_operand" "0")
(const_int 1)]
UNSPEC_ADJBP))]
"!TARGET_KL10up"
"ibp %0"
[(set_attr "reorg_type" "ibp")])
(define_insn "ADJBP"
[(set (match_operand:SI 0 "reg_or_mem_operand" "=rm,x,x")
(unspec:SI
[(match_operand:SI 1 "general_operand" "0,rm,i")
(match_operand:SI 2 "general_operand" "Q,0,0")]
UNSPEC_ADJBP))]
"TARGET_KL10up"
"@
ibp %0
adjbp %0,%1
adjbp %0,[%1]"
[(set_attr "reorg_type" "ibp,none,none")])
(define_insn "MOVEI"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "address_operand" "p")]
UNSPEC_ADDRESS))]
""
{
if (TARGET_EXTENDED)
{
/* ADDRESS: ... */
if (GET_CODE (operands[1]) == CONST_INT
&& !pdp10_const_ok_for_letter_p (INTVAL (operands[1]), 'I'))
return "move %0,[%1]";
else
return "xmovei %0,%a1";
}
else
return "movei %0,%a1";
})
(define_insn "MOVSI"
[(set (match_operand:SI 0 "register_operand" "=r,r")
(ashift:SI (unspec:SI [(match_operand:SI 1 "address_operand" "r,p")]
UNSPEC_ADDRESS)
(const_int 18)))]
""
"@
movs %0,%1
movsi %0,%a1")
(define_insn "HRRI"
[(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,r")
(const_int 18)
(const_int 18))
(unspec:SI [(match_operand:SI 1 "address_operand" "r,p")]
UNSPEC_ADDRESS))]
""
"@
hrr %0,%1
hrri %0,%a1")
(define_insn "HRLI"
[(set (zero_extract:SI (match_operand:SI 0 "register_operand" "+r,r")
(const_int 18)
(const_int 0))
(unspec:SI [(match_operand:SI 1 "address_operand" "r,p")]
UNSPEC_ADDRESS))]
""
"@
hrl %0,%1
hrli %0,%a1")
(define_insn "ADDI"
[(set (match_operand:SI 0 "register_operand" "=r,r,r,r")
(unspec:SI [(plus:SI (match_operand:SI 1 "register_operand" "0,0,0,0")
(match_operand:SI 2 "address_operand" "r,I,i,p"))]
UNSPEC_ADDRESS))]
""
"@
add %0,%2
addi %0,%2
add %0,[%2]
addi %0,%a2")
(define_insn "ashrsi3_pointer"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "immediate_operand" "K")]
UNSPEC_SHIFTRT))]
""
"ash %0,%N2%; ashrsi3_pointer")
(define_insn "ashlsi3_pointer"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "immediate_operand" "K")]
UNSPEC_SHIFT))]
""
"ash %0,%2%; ashlsi3_pointer")
(define_insn "SUBBP"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI [(match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "reg_or_mem_operand" "rm")]
UNSPEC_SUBBP))]
"TARGET_XKL2"
"extend %0,[subbp %2]")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Unconditional Jumps
(define_insn "nop"
[(const_int 0)]
""
;; TODO: this is the traditional NOP instruction. On KL10, TRN is
;; faster.
"jfcl%; nop")
(define_insn "jump"
[(set (pc)
(label_ref (match_operand 0 "" "")))]
""
{
return pdp10_output_jrst (operands[0]);
})
(define_expand "indirect_jump"
[(set (pc)
(match_operand:SI 0 "general_operand" ""))]
""
"/* Strip off any byte pointer fields, leaving only the word address.
TODO: do this earlier, before conversion to 'void *'? */
if (GET_CODE (operands[0]) == CONST_INT)
{
HOST_WIDE_INT address = INTVAL (operands[0]);
address &= TARGET_EXTENDED ? 07777777777 : 0777777;
operands[0] = GEN_INT (address);
}
else if (GET_CODE (operands[0]) == CONST
&& GET_CODE (XEXP (operands[0], 0)) == PLUS
&& GET_CODE (XEXP (XEXP (operands[0], 0), 0)) == SYMBOL_REF
&& GET_CODE (XEXP (XEXP (operands[0], 0), 1)) == CONST_INT)
{
HOST_WIDE_INT offset = INTVAL (XEXP (XEXP (operands[0], 0), 1));
offset &= TARGET_EXTENDED ? 07777777777 : 0777777;
operands[0] = plus_constant (XEXP (XEXP (operands[0], 0), 0), offset);
}")
(define_insn "*indirect_jump"
[(set (pc)
;; ADDRESS: the S constraint allows a symbol.
(match_operand:SI 0 "general_operand" "x,IS,i,rm"))]
""
"@
jrst (%0)
jrst %0
jrst @[%0]
jrst @%0")
(define_expand "call"
[(call (match_operand 0 "memory_operand" "")
(match_operand 1 "general_operand" ""))]
""
"")
(define_insn "*call_reg"
[(call (mem:SI (match_operand:SI 0 "register_operand" "x"))
(match_operand 1 "" "g"))]
""
{
if (pdp10_output_call_as_jrst_p (insn))
return "jrst (%0)";
else
return "pushj 17,(%0)";
})
(define_insn "*call_mem2"
[(call (mem:SI (match_operand 0 "immediate_operand" "i"))
(match_operand 1 "general_operand" "g"))]
"GET_CODE (operands[0]) != SYMBOL_REF"
{
if (pdp10_output_call_as_jrst_p (insn))
return "jrst %a0";
else
return "pushj 17,%a0";
})
(define_insn "*call_symbol"
[(call (mem:SI (match_operand:SI 0 "" "X"))
(match_operand:SI 1 "general_operand" "g"))]
"GET_CODE (operands[0]) == SYMBOL_REF"
{
if (pdp10_output_call_as_jrst_p (insn))
return "jrst %L0";
else
return "pushj 17,%L0";
})
(define_insn "*call_mem1"
[(call (match_operand:SI 0 "memory_operand" "m")
(match_operand:SI 1 "general_operand" "g"))]
""
{
if (pdp10_output_call_as_jrst_p (insn))
return "jrst @%0";
else
return "pushj 17,@%0";
})
(define_expand "call_value"
[(set (match_operand 0 "" "")
(call (match_operand 1 "memory_operand" "")
(match_operand 2 "general_operand" "")))]
""
"")
(define_insn "*call_value_reg"
[(set (match_operand 0 "" "=r")
(call (mem:SI (match_operand:SI 1 "register_operand" "x"))
(match_operand:SI 2 "general_operand" "g")))]
""
{
if (pdp10_output_call_as_jrst_p (insn))
return "jrst (%1)";
else
return "pushj 17,(%1)";
})
(define_insn "*call_value_mem1"
[(set (match_operand 0 "" "=r")
(call (mem:SI (match_operand 1 "memory_operand" "o"))
(match_operand 2 "general_operand" "g")))]
"CONSTANT_ADDRESS_P (XEXP (operands[1], 0))"
{
if (pdp10_output_call_as_jrst_p (insn))
return "jrst @%1";
else
return "pushj 17,@%1";
})
(define_insn "*call_value_mem2"
[(set (match_operand 0 "register_operand" "=r")
(call (mem:SI (match_operand 1 "immediate_operand" "i"))
(match_operand 2 "general_operand" "g")))]
"GET_CODE (operands[1]) != SYMBOL_REF"
{
if (pdp10_output_call_as_jrst_p (insn))
return "jrst %a1";
else
return "pushj 17,%a1";
})
(define_insn "*call_value_symbol"
[(set (match_operand 0 "register_operand" "=r")
(call (mem:SI (match_operand:SI 1 "" "X"))
(match_operand:SI 2 "general_operand" "g")))]
"GET_CODE (operands[1]) == SYMBOL_REF"
{
if (pdp10_output_call_as_jrst_p (insn))
return "jrst %L1";
else if (pdp10_output_call_as_jsp_p (operands[1]))
return "jsp ?,%L1";
else
return "pushj 17,%L1";
})
(define_insn "*call_value_mem3"
[(set (match_operand 0 "register_operand" "=r")
; (call (mem:SI (match_operand:SI 1 "address_operand" "a"))
(call (match_operand:SI 1 "memory_operand" "m")
(match_operand:SI 2 "general_operand" "g")))]
""
{
/* operands[1] = gen_rtx_MEM (SImode, operands[1]);*/
if (pdp10_output_call_as_jrst_p (insn))
return "jrst %1";
else
return "pushj 17,%1";
})
; (define_expand "sibcall" ...)
; (define_expand "sibcall_value" ...)
(define_expand "untyped_call"
[(parallel [(call (match_operand 0 "" "")
(const_int 0))
(match_operand 1 "" "")
(match_operand 2 "" "")])]
""
"{
int i;
emit_call_insn (gen_call (operands[0], const0_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));
}
/* The optimizer doesn't know that the call sets the function value
registers we stored in the result block. We avoid problems by
claiming that all hard registers are used and clobbered at this
point. */
emit_insn (gen_blockage ());
DONE;
}")
(define_insn "*PUSHJ"
[(parallel
[(call (match_operand:SI 0 "memory_operand" "m")
(match_operand:SI 1 "" ""))
(use (match_operand:SI 2 "register_operand" "+r"))])]
""
"pushj %2,%0")
; (define_insn "trap"
; [(trap_if (const_int 1) (const_int 0))]
; ""
; "<trap 0>%; trap")
(define_expand "casesi"
[(set (match_dup 5)
(minus:SI (match_operand:SI 0 "register_operand" "")
(match_operand:SI 1 "general_operand" "")))
(set (pc)
(if_then_else (lt (match_dup 5) (const_int 0))
(label_ref (match_operand 4 "" ""))
(pc)))
(set (pc)
(if_then_else (gt (match_dup 5)
(match_operand:SI 2 "general_operand" ""))
(label_ref (match_dup 4))
(pc)))
;;; This is too general. The jump table label will always be local.
;;; Unless the table is in .rodata located in another section.
; (set (match_dup 6)
; (plus:SI (match_dup 5) (label_ref (match_operand 3 "" ""))))
; (parallel [(set (pc) (if_then_else (const_int 1)
; (mem:SI (match_dup 6))
; (label_ref (match_dup 4))))
; (use (label_ref (match_dup 3)))])]
(parallel [(set (pc)
(if_then_else
(const_int 1)
(mem:SI (plus:SI (match_dup 5)
(label_ref (match_operand 3 "" ""))))
(label_ref (match_dup 4))))
(use (label_ref (match_dup 3)))])]
""
"operands[5] = gen_reg_rtx (SImode);
/*operands[6] = gen_reg_rtx (SImode);*/")
;; This is the bare minimum of how an acceptable casesi dispatch
;; instruction must look like.
(define_insn ""
[(parallel [(set (pc)
(if_then_else (const_int 1)
(match_operand:SI 0 "address_operand" "p")
(label_ref (match_operand 1 "" ""))))
(use (label_ref (match_operand 2 "" "")))])]
""
"jrst %a0")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Conditional Jumps
(define_expand "cmpsi"
[(set (cc0) (compare (match_operand:SI 0 "register_operand" "")
(match_operand:SI 1 "general_operand" "")))]
""
"pdp10_compare_op0 = operands[0];
pdp10_compare_op1 = operands[1];
DONE;")
;; (define_expand "cmpdi"
;; [(set (cc0) (compare (match_operand:DI 0 "register_operand" "")
;; (match_operand:DI 1 "general_operand" "")))]
;; ""
;; "pdp10_compare_op0 = operands[0];
;; pdp10_compare_op1 = operands[1];
;; DONE;")
(define_expand "cmpsf"
[(set (cc0) (compare (match_operand:SF 0 "register_operand" "")
(match_operand:SF 1 "general_operand" "")))]
""
"pdp10_compare_op0 = operands[0];
pdp10_compare_op1 = operands[1];
DONE;")
;; KCC generates this for double x, y:
;; x == y:
;; CAMN x+1,y+1
;; CAME x,y
;; ;here if false
;; x < y: x<y x==y x>y
;; CAML x,y ? false false
;; CAMGE x+1,y+1 false true ?
;; CAMLE x,y true false
;; ;here if false no yes yes
;; x <= y:
;; CAML x,y ? false false
;; CAMG x+1,y+1 false false ?
;; CAMLE x,y true true false
;; ;here if false no no yes
;; These may also work for long long after adaptions.
;; To compare a double against zero:
;; x < 0:
;; JUMPL x,label
;; ;here if false
;; x >= 0:
;; JUMPGE x,label
;; ;here if false
;; x <= 0: x<0 x==0 x>0
;; JUMPL x,label true false false
;; SKIPN x false
;; JUMPE x+1,label true
;; ;here if false
;; x > 0:
;; JUMPG x,label false false maybe
;; SKIPL x true false false
;; JUMPG x+1,label false true
;; ;here if false
(define_expand "cmpdf"
[(set (cc0) (compare (match_operand:DF 0 "register_operand" "")
(match_operand:DF 1 "general_operand" "")))]
""
"if (pdp10_const_double_0_operand (operands[1], DFmode))
pdp10_compare_op0 = operands[0];
else
{
pdp10_compare_op0 = gen_reg_rtx (DFmode);
gen_subdf3 (pdp10_compare_op0, operands[0], operands[1]);
}
pdp10_compare_op1 = CONST0_RTX (DFmode);
DONE;")
(define_insn "test_and_skip"
[(set (pc)
(if_then_else
(match_operator 0 "pdp10_equality_operator"
[(and:SI (match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "general_operand" "g"))
(const_int 0)])
(label_ref (match_operand 3 "" ""))
(pc)))]
""
"*pdp10_remove_unnecessary_label (insn, operands[3]);
return pdp10_output_test_and_skip (insn, operands);"
[(set (attr "length")
(if_then_else (eq (minus (match_dup 3) (pc)) (const_int 1))
(const_int 1)
(const_int 2)))
(set_attr "skip" "yes")])
;; Equality comparisons of a contigous group of bits with zero will be
;; written using zero_extract rather than the equivalent AND operations.
(define_insn "test_extract_skip"
[(set (pc)
(if_then_else
(match_operator 0 "pdp10_equality_operator"
[(zero_extract:SI
(match_operand:SI 1 "register_operand" "r")
(match_operand:SI 2 "const_int_operand" "")
(match_operand:SI 3 "const_int_operand" ""))
(const_int 0)])
(label_ref (match_operand 4 "" ""))
(pc)))]
""
{
int len = INTVAL (operands[2]), pos = INTVAL (operands[3]);
HOST_WIDE_INT mask = (((HOST_WIDE_INT)1 << len) - 1) << (36 - pos - len);
/* Must assign operands[2] and operands[3], since
pdp10_output_test_and_skip use those to output the
instruction. */
operands[2] = gen_int_mode (mask, SImode);
operands[3] = operands[4];
pdp10_remove_unnecessary_label (insn, operands[3]);
return pdp10_output_test_and_skip (insn, operands);
}
[(set (attr "length")
(if_then_else (eq (minus (match_dup 4) (pc)) (const_int 1))
(const_int 1)
(const_int 2)))
(set_attr "skip" "yes")])
(define_insn "TLZN"
[(set (pc)
(if_then_else
(ne (and:SI (match_operand:SI 0 "register_operand" "+r")
(match_operand:SI 1 "const_int_operand" ""))
(const_int 0))
(label_ref (match_operand 2 "" ""))
(pc)))
(set (match_dup 0) (and:SI (match_dup 0) (not:SI (match_dup 1))))]
""
{
pdp10_remove_unnecessary_label (insn, operands[2]);
if (get_attr_length (insn) == 1)
return "tlzn %0,%1";
else
return "tlze %0,%1\;jrst %2";
}
[(set (attr "length")
(if_then_else (eq (minus (match_dup 2) (pc)) (const_int 1))
(const_int 1)
(const_int 2)))
(set_attr "skip" "yes")])
(define_insn "TLNE_TLZA_TLO"
[(set (match_operand:SI 0 "register_operand" "+r")
(unspec:SI [(match_dup 0)
(match_operand:SI 1 "const_int_operand" "")
(match_operand:SI 2 "const_int_operand" "")
(match_operand:SI 3 "const_int_operand" "")]
UNSPEC_TLNE_TLZA_TLO))]
""
"tlne %0,%1\;%_tlza %0,%2\;%_%_tlo %0,%3"
[(set_attr "length" "3")])
(define_expand "bne"
[(set (pc)
(if_then_else (ne (match_dup 1) (match_dup 2))
(label_ref (match_operand 0 "" ""))
(pc)))]
""
"if (pdp10_generate_cbranchdi (NE, pdp10_compare_op0, pdp10_compare_op1))
DONE;
operands[1] = pdp10_compare_op0;
operands[2] = pdp10_compare_op1;")
(define_expand "beq"
[(set (pc)
(if_then_else (eq (match_dup 1) (match_dup 2))
(label_ref (match_operand 0 "" ""))
(pc)))]
""
"operands[1] = pdp10_compare_op0;
operands[2] = pdp10_compare_op1;")
(define_expand "bge"
[(set (pc)
(if_then_else (ge (match_dup 1) (match_dup 2))
(label_ref (match_operand 0 "" ""))
(pc)))]
""
"operands[1] = pdp10_compare_op0;
operands[2] = pdp10_compare_op1;")
(define_expand "bgt"
[(set (pc)
(if_then_else (gt (match_dup 1) (match_dup 2))
(label_ref (match_operand 0 "" ""))
(pc)))]
""
"operands[1] = pdp10_compare_op0;
operands[2] = pdp10_compare_op1;")
(define_expand "ble"
[(set (pc)
(if_then_else (le (match_dup 1) (match_dup 2))
(label_ref (match_operand 0 "" ""))
(pc)))]
""
"operands[1] = pdp10_compare_op0;
operands[2] = pdp10_compare_op1;")
(define_expand "blt"
[(set (pc)
(if_then_else (lt (match_dup 1) (match_dup 2))
(label_ref (match_operand 0 "" ""))
(pc)))]
""
"operands[1] = pdp10_compare_op0;
operands[2] = pdp10_compare_op1;")
(define_expand "bgeu"
[(set (pc)
(if_then_else (ge (match_dup 1) (match_dup 2))
(label_ref (match_operand 0 "" ""))
(pc)))]
""
"operands[1] = pdp10_flip_sign_bit (pdp10_compare_op0);
operands[2] = pdp10_flip_sign_bit (pdp10_compare_op1);")
(define_expand "bgtu"
[(set (pc)
(if_then_else (gt (match_dup 1) (match_dup 2))
(label_ref (match_operand 0 "" ""))
(pc)))]
""
"operands[1] = pdp10_flip_sign_bit (pdp10_compare_op0);
operands[2] = pdp10_flip_sign_bit (pdp10_compare_op1);")
(define_expand "bleu"
[(set (pc)
(if_then_else (le (match_dup 1) (match_dup 2))
(label_ref (match_operand 0 "" ""))
(pc)))]
""
"operands[1] = pdp10_flip_sign_bit (pdp10_compare_op0);
operands[2] = pdp10_flip_sign_bit (pdp10_compare_op1);")
(define_expand "bltu"
[(set (pc)
(if_then_else (lt (match_dup 1) (match_dup 2))
(label_ref (match_operand 0 "" ""))
(pc)))]
""
"operands[1] = pdp10_flip_sign_bit (pdp10_compare_op0);
operands[2] = pdp10_flip_sign_bit (pdp10_compare_op1);")
; (define_insn "cbranchsi4" ...)
(define_insn "cbranchsi"
[(set (pc)
(if_then_else (match_operator 3 "comparison_operator"
[(match_operand:SI 1 "reg_or_mem_operand" "r,m,r,r,r")
;; ADDRESS: an S constraint for the cai case
;; (alternative 2) would allow a symbol.
(match_operand:SI 2 "general_operand" "O,O,I,i,rm")])
(label_ref (match_operand 0 "" ""))
(pc)))]
""
{
static const char *asms[] =
{ "jump%3 %1,%F0",
"skip%3 %@%1",
"cai%3 %1,%2",
"cam%3 %1,[%X2]",
"cam%3 %1,%2" };
if (which_alternative != 0)
pdp10_remove_unnecessary_label (insn, operands[0]);
/* ADDRESS: unextended code can store the symbol in the immediate
field. */
if (which_alternative == 3 && !TARGET_EXTENDED
&& GET_CODE (operands[2]) == CONST)
which_alternative = 2;
if (get_attr_length (insn) == 1)
return asms[which_alternative];
else
{
/* Reverse the skip condition and output a JRST. */
operands[3] = gen_rtx_fmt_ee (reverse_condition
(GET_CODE (operands[3])),
VOIDmode, NULL_RTX, NULL_RTX);
output_asm_insn (asms[which_alternative], operands);
return pdp10_output_jrst (operands[0]);
}
}
[(set (attr "length")
(if_then_else (ior (eq_attr "alternative" "0")
(eq (minus (match_dup 0) (pc)) (const_int 1)))
(const_int 1)
(const_int 2)))
(set_attr "skip" "no,yes,yes,yes,yes")])
(define_insn "*CAI_reg"
[(set (pc)
(if_then_else (match_operator 0 "comparison_operator"
[(and:SI (match_operand:SI 1 "register_operand" "x")
(const_int RIGHT_HALF))
(match_operand:SI 2 "register_operand" "r")])
(label_ref (match_operand 3 "" ""))
(pc)))]
""
{
pdp10_remove_unnecessary_label (insn, operands[3]);
if (get_attr_length (insn) == 1)
return "cai%0 %2,(%1)";
else
{
/* Reverse the skip condition and output a JRST. */
output_asm_insn ("cai%R0 %2,(%1)", operands);
return pdp10_output_jrst (operands[3]);
}
}
[(set (attr "length")
(if_then_else (eq (minus (match_dup 3) (pc)) (const_int 1))
(const_int 1)
(const_int 2)))
(set_attr "skip" "yes")])
(define_insn "*CAI_const_plus_reg"
[(set (pc)
(if_then_else (match_operator 0 "comparison_operator"
[(and:SI (plus:SI
(match_operand:SI 1 "register_operand" "x")
(match_operand:SI 2 "const_int_operand" "I"))
(const_int RIGHT_HALF))
(match_operand:SI 3 "register_operand" "r")])
(label_ref (match_operand 4 "" ""))
(pc)))]
"pdp10_const_ok_for_letter_p (INTVAL (operands[2]), 'I')"
{
pdp10_remove_unnecessary_label (insn, operands[4]);
if (get_attr_length (insn) == 1)
return "cai%0 %3,%2(%1)";
else
{
/* Reverse the skip condition and output a JRST. */
output_asm_insn ("cai%R0 %3,%2(%1)", operands);
return pdp10_output_jrst (operands[4]);
}
}
[(set (attr "length")
(if_then_else (eq (minus (match_dup 4) (pc)) (const_int 1))
(const_int 1)
(const_int 2)))
(set_attr "skip" "yes")])
(define_insn "*cbranchsf"
[(set (pc)
(if_then_else (match_operator 3 "pdp10_comparison_operator"
[(match_operand:SF 1 "reg_or_mem_operand" "r,m,r,r,r")
(match_operand:SF 2 "general_operand" "R,R,I,i,rm")])
(label_ref (match_operand 0 "" ""))
(pc)))]
""
{
/* TODO: Copy from cbranchsi. Maybe create an output function for
both? */
const char *asms[][2] =
{ { "jump%3 %1,%F0", 0 },
{ "skip%3 %@%1", "skip%R3 %@%1\;jrst %l0" },
{ "cai%3 %1,%2", "cai%R3 %1,%2\;jrst %l0" },
{ "cam%3 %1,[%2]", "cam%R3 %1,[%2]\;jrst %l0" },
{ "cam%3 %1,%2", "cam%R3 %1,%2\;jrst %l0" } };
if (which_alternative != 0)
pdp10_remove_unnecessary_label (insn, operands[0]);
return asms[which_alternative][get_attr_length (insn) - 1];
}
[(set (attr "length")
(if_then_else (ior (eq_attr "alternative" "0")
(eq (minus (match_dup 0) (pc)) (const_int 1)))
(const_int 1)
(const_int 2)))
(set_attr "skip" "no,yes,yes,yes,yes")])
(define_insn "*cbranchdf"
[(set (pc)
(if_then_else
(match_operator 3 "pdp10_comparison_operator"
[(match_operand:DF 1 "reg_or_mem_operand" "r,m")
(match_operand:DF 2 "pdp10_const_double_0_operand" "")])
(label_ref (match_operand 0 "" ""))
(pc)))]
""
{
if (which_alternative == 0)
return "jump%3 %1,%F0";
pdp10_remove_unnecessary_label (insn, operands[0]);
if (get_attr_length (insn) == 1)
return "skip%3 %@%1";
else
{
output_asm_insn ("skip%R3 %@%1", operands);
return pdp10_output_jrst (operands[0]);
}
}
[(set (attr "length")
(if_then_else (ior (eq_attr "alternative" "0")
(eq (minus (match_dup 0) (pc)) (const_int 1)))
(const_int 1)
(const_int 2)))
(set_attr "skip" "no,yes")])
(define_insn "doloop_end"
[(set (pc)
(if_then_else
(ge (plus:SI (match_operand:SI 0 "reg_or_mem_operand" "+r")
(const_int -1))
(const_int 0))
(label_ref (match_operand 4 "" ""))
(pc)))
(set (match_dup 0)
(plus:SI (match_dup 0) (const_int -1)))
(use (match_operand 1 "" "")) ; iterations; zero if unknown
(use (match_operand 2 "" "")) ; max iterations
(use (match_operand 3 "" ""))] ; loop level
""
"sojge %0,%l4%; doloop_end")
(define_insn "decrement_and_branch_until_zero"
[(set (pc)
(if_then_else
(match_operator 2 "pdp10_comparison_operator"
[(plus:SI (match_operand:SI 0 "reg_or_mem_operand" "+r,m")
(const_int -1))
(const_int 0)])
(label_ref (match_operand 1 "" ""))
(pc)))
(set (match_dup 0)
(plus:SI (match_dup 0) (const_int -1)))]
""
{
if (which_alternative == 0)
return "soj%2 %0,%l1%; decrement_and_branch_until_zero";
pdp10_remove_unnecessary_label (insn, operands[1]);
if (get_attr_length (insn) == 1)
return "sos%2 %@%0%; decrement_and_branch_until_zero";
else
{
output_asm_insn ("sos%R2 %@%0%; decrement_and_branch_until_zero",
operands);
return pdp10_output_jrst (operands[1]);
}
}
[(set (attr "length")
(if_then_else (ior (eq_attr "alternative" "0")
(eq (minus (match_dup 1) (pc)) (const_int 1)))
(const_int 1)
(const_int 2)))
(set_attr "skip" "no,yes")])
(define_insn "*AOJ"
[(set (pc)
(if_then_else
(match_operator 0 "pdp10_comparison_operator"
[(plus:SI (match_operand:SI 1 "reg_or_mem_operand" "+r,m")
(const_int 1))
(const_int 0)])
(label_ref (match_operand 2 "" ""))
(pc)))
(set (match_dup 1)
(plus:SI (match_dup 1) (const_int 1)))]
""
{
if (which_alternative == 0)
return "aoj%0 %1,%l2";
pdp10_remove_unnecessary_label (insn, operands[2]);
if (get_attr_length (insn) == 1)
return "aos%0 %@%1";
else
{
output_asm_insn ("aos%R0 %@%1", operands);
return pdp10_output_jrst (operands[2]);
}
}
[(set (attr "length")
(if_then_else (ior (eq_attr "alternative" "0")
(eq (minus (match_dup 2) (pc)) (const_int 1)))
(const_int 1)
(const_int 2)))
(set_attr "skip" "no,yes")])
(define_insn "*SOJA"
[(set (pc)
(label_ref (match_operand 2 "" "")))
(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (match_operand:SI 1 "register_operand" "0")
(const_int -1)))]
""
{
rtx next = next_nonnote_insn (insn);
if (next == operands[2]
|| (GET_CODE (next) == BARRIER
&& next_nonnote_insn (next) == operands[2]))
{
pdp10_remove_unnecessary_label (insn, operands[1]);
return "subi %0,1";
}
else
return "soja %0,%l2";
})
(define_insn "*AOJA"
[(set (pc)
(label_ref (match_operand 2 "" "")))
(set (match_operand:SI 0 "register_operand" "=r")
(plus:SI (match_operand:SI 1 "register_operand" "0")
(const_int 1)))]
""
{
rtx next = next_nonnote_insn (insn);
if (next == operands[2]
|| (GET_CODE (next) == BARRIER
&& next_nonnote_insn (next) == operands[2]))
{
pdp10_remove_unnecessary_label (insn, operands[2]);
return "addi %0,1";
}
else
return "aoja %0,%l2";
})
(define_insn "*SOSx_and_move"
[(set (pc)
(if_then_else
(match_operator 2 "pdp10_comparison_operator"
[(plus:SI (match_operand:SI 1 "reg_or_mem_operand" "+rm")
(const_int -1))
(const_int 0)])
(label_ref (match_operand 3 "" ""))
(pc)))
(set (match_dup 1)
(plus:SI (match_dup 1) (const_int -1)))
(set (match_operand:SI 0 "register_operand" "=x")
(plus:SI (match_dup 1) (const_int -1)))]
""
{
pdp10_remove_unnecessary_label (insn, operands[3]);
if (get_attr_length (insn) == 1)
return "sos%2 %0,%1";
else
{
output_asm_insn ("sos%R2 %0,%1", operands);
return pdp10_output_jrst (operands[3]);
}
}
[(set (attr "length")
(if_then_else (eq (minus (match_dup 3) (pc)) (const_int 1))
(const_int 1)
(const_int 2)))
(set_attr "skip" "yes")])
(define_insn "*AOSx_and_move"
[(set (pc)
(if_then_else
(match_operator 2 "pdp10_comparison_operator"
[(plus:SI (match_operand:SI 1 "reg_or_mem_operand" "+rm")
(const_int 1))
(const_int 0)])
(label_ref (match_operand 3 "" ""))
(pc)))
(set (match_dup 1)
(plus:SI (match_dup 1) (const_int 1)))
(set (match_operand:SI 0 "register_operand" "=x")
(plus:SI (match_dup 1) (const_int 1)))]
""
{
pdp10_remove_unnecessary_label (insn, operands[3]);
if (get_attr_length (insn) == 1)
return "aos%2 %0,%1";
else
{
output_asm_insn ("aos%R2 %0,%1", operands);
return pdp10_output_jrst (operands[3]);
}
}
[(set (attr "length")
(if_then_else (eq (minus (match_dup 3) (pc)) (const_int 1))
(const_int 1)
(const_int 2)))
(set_attr "skip" "yes")])
(define_insn "JFFO"
[(set (pc)
(if_then_else (ne (subreg:SI
(match_operand:DI 0 "register_operand" "+r") 0)
(const_int 0))
(match_operand 1 "address_operand" "")
(pc)))
(set (subreg:SI (match_dup 0) 4)
(unspec:SI [(subreg:SI (match_dup 0) 0)] UNSPEC_FFO))]
"TARGET_KA10up"
{
if (GET_CODE (operands[1]) == LABEL_REF)
return "jffo %0,%l1";
else
return "jffo %0,%1";
})
(define_insn "CMPBP"
[(set (pc)
(if_then_else
(match_operator 0 "comparison_operator"
[(unspec:SI
[(match_operand:SI 1 "register_operand" "r")] UNSPEC_CMPBP)
(unspec:SI
[(match_operand:SI 2 "reg_or_mem_operand" "rm")] UNSPEC_CMPBP)])
(label_ref (match_operand 3 "" ""))
(pc)))]
"TARGET_XKL2"
{
pdp10_remove_unnecessary_label (insn, operands[3]);
if (get_attr_length (insn) == 1)
return "extend %1,[cmpbp%0 %2]";
else
return "extend %1,[cmpbp%C0 %2]\;jump %3";
}
[(set (attr "length")
(if_then_else (eq (minus (match_dup 3) (pc)) (const_int 1))
(const_int 1)
(const_int 2)))
(set_attr "skip" "yes")])
; (define_expand "conditional_trap"
; [(trap_if (match_operator 0 "pdp10_comparison_operator"
; [(match_dup 2) (const_int 0)])
; (match_operand 1 "const_int_operand" ""))]
; ""
; "operands[2] = pdp10_compare_op0;")
; (define_insn "*trap"
; [(trap_if (match_operator 0 "pdp10_comparison_operator"
; [(match_operand 2 "memory_operand" "m") (const_int 0)])
; (match_operand 1 "const_int_operand" "i"))]
; ""
; "skip%R0 %2\;%_<trap %1>%; conditional_trap"
; [(set_attr "length" "2")])
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Function Prologue and Epilogue
(define_expand "prologue"
[(const_int 2)]
""
"pdp10_expand_prologue ();
DONE;")
(define_expand "epilogue"
[(return)]
""
"pdp10_expand_epilogue (1);
DONE;")
(define_expand "sibcall_epilogue"
[(const_int 3)]
""
"pdp10_expand_epilogue (0);
DONE;")
(define_insn "POPJ"
[(set (pc) (match_operand:SI 0 "pdp10_pop_operand" ""))]
""
"popj %P0,")
(define_insn "POPJ_17"
[(return)]
""
{
return pdp10_output_return ();
})
;; Allocate stack space, and return the word address of the allocated
;; memory.
(define_expand "allocate_stack"
[(set (match_operand:SI 0 "register_operand" "")
(unspec:SI [(plus:SI (reg:SI SP_REGNUM) (const_int 1))]
UNSPEC_ADDRESS))
(set (reg:SI SP_REGNUM)
(unspec:SI
[(reg:SI SP_REGNUM)
(match_operand:SI 1 "general_operand" "")]
UNSPEC_ADJSP))]
""
"{
rtx x = plus_constant (stack_pointer_rtx, 1);
rtx y, z = gen_reg_rtx (Pmode);
if (GET_CODE (operands[1]) == CONST_INT)
y = GEN_INT ((INTVAL (operands[1]) + 3) / 4);
else
{
y = gen_reg_rtx (Pmode);
emit_insn (gen_addsi3 (y, operands[1], GEN_INT (3)));
emit_insn (gen_ASH_right (y, y, GEN_INT (-2)));
}
emit_move_insn (z,
gen_rtx_UNSPEC (Pmode, gen_rtvec (1, x), UNSPEC_ADDRESS));
emit_move_insn (operands[0], z);
emit_insn (pdp10_gen_stack_adjust (y));
DONE;
}")
(define_expand "ADJSP"
[(set (match_operand:SI 0 "register_operand" "")
(unspec:SI [(match_dup 0) (match_operand:SI 1 "general_operand" "")]
UNSPEC_ADJSP))]
""
"")
(define_insn "*ADJSP_KL10up"
[(set (match_operand:SI 0 "register_operand" "+r,r,r,r")
(unspec:SI [(match_dup 0)
(match_operand:SI 1 "general_operand" "K,i,x,m")]
UNSPEC_ADJSP))]
"TARGET_KL10up"
"@
adjsp %0,%1
adjsp %0,[%1]
adjsp %0,(%1)
adjsp %0,@%1")
(define_insn "*ADJSP_noKL10up"
[(set (match_operand:SI 0 "register_operand" "+r")
(unspec:SI [(match_dup 0)
(match_operand:SI 1 "immediate_operand" "K")]
UNSPEC_ADJSP))]
"!TARGET_KL10up && !TARGET_EXTENDED"
"add %0,[%1,,%1]")
(define_insn "PUSH"
[(set (match_operand:SI 0 "pdp10_push_operand" "=m")
(match_operand:SI 1 "reg_or_mem_operand" "rm"))]
""
"push %P0,%1")
(define_insn "*pushsi_combine"
[(parallel
[(set (mem:SI (plus:SI (match_operand:SI 0 "register_operand" "r")
(const_int 1)))
;; FIXME: empty predicate allowed?
(match_operand:SI 1 "" "rm"))
(set (match_operand:SI 2 "register_operand" "=0")
(plus:SI (match_dup 0) (const_int 1)))])]
"optimize_size && TARGET_EXTENDED"
"push %0,%1")
(define_insn "*pushsf_combine"
[(parallel
[(set (mem:SF (plus:SI (match_operand:SI 0 "register_operand" "r")
(const_int 1)))
(match_operand:SF 1 "reg_or_mem_operand" "rm"))
(set (match_operand:SI 2 "register_operand" "=0")
(plus:SI (match_dup 0) (const_int 1)))])]
"optimize_size && TARGET_EXTENDED"
"push %0,%1")
(define_insn "POP"
[(set (match_operand:SI 0 "reg_or_mem_operand" "=rm")
(match_operand:SI 1 "pdp10_pop_operand" "m"))]
""
"pop %P1,%0")
(define_insn "*popsi_combine"
[(parallel
[(set (match_operand:SI 0 "reg_or_mem_operand" "=rm")
(mem:SI (match_operand:SI 1 "register_operand" "r")))
(set (match_operand:SI 2 "reg_or_mem_operand" "=1")
(plus:SI (match_dup 1) (const_int -1)))])]
"optimize_size && TARGET_EXTENDED"
"pop %1,%0")
(define_insn "*popsf_combine"
[(parallel
[(set (match_operand:SF 0 "reg_or_mem_operand" "=rm")
(mem:SF (match_operand:SI 1 "register_operand" "+r")))
(set (match_dup 1)
(plus:SI (match_dup 1) (const_int -1)))])]
"optimize_size && TARGET_EXTENDED"
"pop %1,%0")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Peepholes
;; The following four insns compensate for unnecessary shifts
;; generated by pointer arithmetic.
(define_insn "*combine_nop_shift_left_right"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI
[(ashift:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "const_int_operand" ""))
(match_operand:SI 3 "const_int_operand" "")]
UNSPEC_SHIFTRT))]
"INTVAL (operands[2]) == INTVAL (operands[3])"
""
[(set_attr "length" "0")])
(define_insn "*combine_shift_left_right"
[(set (match_operand:SI 0 "register_operand" "=r")
(unspec:SI
[(ashift:SI (match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "const_int_operand" ""))
(match_operand:SI 3 "const_int_operand" "")]
UNSPEC_SHIFTRT))]
""
{
operands[2] = GEN_INT (INTVAL (operands[2]) - INTVAL (operands[3]));
return "ash %0,%2";
})
(define_insn "*combine_nop_shift_right_left"
[(set (match_operand:SI 0 "register_operand" "=r")
(ashiftrt:SI
(unspec:SI [(match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "const_int_operand" "")]
UNSPEC_SHIFT)
(match_operand:SI 3 "const_int_operand" "")))]
"INTVAL (operands[2]) == INTVAL (operands[3])"
""
[(set_attr "length" "0")])
(define_insn "*combine_shift_right_left"
[(set (match_operand:SI 0 "register_operand" "=r")
(ashiftrt:SI
(unspec:SI [(match_operand:SI 1 "register_operand" "0")
(match_operand:SI 2 "const_int_operand" "")]
UNSPEC_SHIFT)
(match_operand:SI 3 "const_int_operand" "")))]
""
{
operands[2] = GEN_INT (INTVAL (operands[2]) - INTVAL (operands[3]));
return "ash %0,%2";
})
;; Remove unnecessary shifts generated by pointer arithmetic.
(define_peephole2
[(set (match_operand:SI 0 "register_operand" "")
(unspec:SI
[(truncate:SI
(ashift:SI (match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "const_int_operand" "")))
(match_operand:SI 3 "const_int_operand" "")]
UNSPEC_SHIFTRT))]
"INTVAL (operands[2]) == INTVAL (operands[3])"
[(set (match_dup 0) (truncate:SI (match_dup 1)))])
(define_peephole2
[(set (match_operand:SI 0 "register_operand" "")
(ashiftrt:SI
(unspec:SI [(match_operand:SI 1 "register_operand" "")
(match_operand:SI 2 "const_int_operand" "")]
UNSPEC_SHIFT)
(match_operand:SI 3 "const_int_operand" "")))]
"INTVAL (operands[2]) == INTVAL (operands[3])"
[(set (match_dup 0) (match_dup 1))])
;; Generate EXCH instructions.
(define_peephole2
[(set (match_operand:SI 0 "register_operand" "")
(match_operand:SI 1 "reg_or_mem_operand" ""))
(set (match_dup 1)
(match_operand:SI 2 "reg_or_mem_operand" ""))
(set (match_dup 2)
(match_dup 0))]
"find_reg_note (next_nonnote_insn (next_nonnote_insn (insn)),
REG_DEAD, operands[0])
&& (register_operand (operands[1], SImode)
|| register_operand (operands[2], SImode))"
;"peep2_reg_dead_p (2, operands[0]) && ..."
[(parallel [(set (match_dup 1) (match_dup 2))
(set (match_dup 2) (match_dup 1))])]
"if (register_operand (operands[1], SImode))
{
rtx tmp = operands[1];
operands[1] = operands[2];
operands[2] = tmp;
}")
;; Generate SETZB instructions.
(define_peephole2
[(set (match_operand:SI 0 "reg_or_mem_operand" "") (const_int 0))
(set (match_operand:SI 1 "reg_or_mem_operand" "") (const_int 0))]
"register_operand (operands[0], SImode)
|| register_operand (operands[1], SImode)"
[(parallel [(set (match_dup 0) (const_int 0))
(set (match_dup 1) (const_int 0))])]
"if (register_operand (operands[0], SImode))
{
rtx tmp = operands[0];
operands[0] = operands[1];
operands[1] = tmp;
}")
;; Remove an unneccesary MOVEI instruction.
(define_peephole2
[(set (match_operand:SI 0 "register_operand" "")
(unspec:SI
[(plus:SI (match_dup 0) (match_operand 1 "const_int_operand" ""))]
UNSPEC_ADDRESS))
(parallel [(unspec_volatile:BLK
[(match_operand:SI 2 "register_operand" "")]
VUNSPEC_BLT)
(use (mem:BLK (match_dup 0)))])]
"dead_or_set_p (insn, operands[0])"
;"peep2_reg_dead_p (0, operands[0])"
[(parallel [(unspec_volatile:BLK [(match_dup 2)] VUNSPEC_BLT)
(use (mem:BLK (plus:SI (match_dup 0) (match_dup 1))))])])
;; Optimize a block-copy operation with constant addresses.
(define_peephole2
[(set (match_operand:SI 0 "register_operand" "")
(unspec:SI
[(match_operand:SI 1 "immediate_operand" "")] UNSPEC_ADDRESS))
(set (zero_extract:SI (match_dup 0) (const_int 18) (const_int 0))
(unspec:SI
[(match_operand:SI 2 "immediate_operand" "")] UNSPEC_ADDRESS))]
""
[(set (match_dup 0)
(ior:SI (ashift:SI (match_dup 2) (const_int 18))
(match_dup 1)))])
;; Optimize a block-clear operation with a constant address.
(define_peephole2
[(set (match_operand:SI 0 "register_operand" "")
(match_operand:SI 1 "immediate_operand" ""))
(set (match_operand:SI 2 "register_operand" "")
(ashift:SI (unspec:SI [(match_dup 0)] UNSPEC_ADDRESS)
(const_int 18)))
(set (zero_extract:SI (match_dup 2) (const_int 18) (const_int 18))
;; FIXME: (const_int 4) -> (const_int 1)?
(unspec:SI [(plus:SI (match_dup 0) (const_int 4))] UNSPEC_ADDRESS))]
"dead_or_set_p (insn, operands[0])"
;"peep2_reg_dead_p (0, operands[0])"
[(set (match_dup 2)
(ior:SI (ashift:SI (match_dup 1) (const_int 18))
(const:SI (plus:SI (match_dup 1) (const_int 1)))))])
;; Generate a PUSHJ instruction from an equivalent sequence of
;; instructions.
(define_peephole2
[(set (match_operand:SI 0 "register_operand" "")
(label_ref:SI (match_operand 1 "" "")))
(parallel
[(set (mem:SI (plus:SI (match_operand:SI 2 "register_operand" "")
(const_int 1)))
(match_operand:SI 3 "" ""))
(set (match_dup 2)
(plus:SI (match_dup 2) (const_int 1)))])
(set (pc)
(match_operand:SI 4 "" ""))]
;; TODO: find code_label corresponding to operands[1].
"0 && TARGET_EXTENDED"
[(parallel
[(call (mem:SI (match_dup 4)) (const_int 0))
(use (match_dup 2))])])
;; Generate a POP instruction from an equivalent sequence of
;; instructions.
(define_peephole2
[(set (match_operand:SI 0 "register_operand" "")
(mem:SI (match_operand:SI 1 "register_operand" "")))
(set (match_operand:SI 2 "reg_or_mem_operand" "")
(match_dup 0))
(set (match_dup 1)
(plus:SI (match_dup 1) (const_int -1)))]
"optimize_size && TARGET_EXTENDED"
[(parallel
[(set (match_dup 2)
(mem:SI (match_dup 1)))
(set (match_dup 1)
(plus:SI (match_dup 1) (const_int -1)))])])
(define_peephole2
[(set (match_operand:SF 0 "register_operand" "")
(mem:SF (match_operand:SI 1 "register_operand" "")))
(set (match_operand:SF 2 "reg_or_mem_operand" "")
(match_dup 0))
(set (match_dup 1)
(plus:SI (match_dup 1) (const_int -1)))]
"optimize_size && TARGET_EXTENDED"
[(parallel
[(set (match_dup 2)
(mem:SF (match_dup 1)))
(set (match_dup 1)
(plus:SI (match_dup 1) (const_int -1)))])])
;; XMOVEI AC1,OFFSET(17)
;; MOVE AC2,AC1 -> MOVE AC2,OFFSET(17)
;; AC1 is dead
(define_peephole2
[(set (match_operand:SI 1 "register_operand" "")
(plus:SI (reg:SI SP_REGNUM)
(match_operand:SI 2 "const_int_operand" "")))
(set (match_operand:SI 0 "register_operand" "")
(match_dup 1))]
;"dead_or_set_p (insn, operands[1])"
"find_regno_note (next_real_insn (insn), REG_DEAD, REGNO (operands[1]))"
;"peep2_reg_dead_p (1, operands[1]);"
[(set (match_dup 0)
(plus:SI (reg:SI SP_REGNUM) (match_dup 2)))])
;; XMOVEI AC1,(17)
;; ADDI AC1,OFFSET -> XMOVEI AC1,OFFSET(17)
(define_peephole2
[(set (match_operand:SI 0 "register_operand" "")
(reg:SI SP_REGNUM))
(set (match_dup 0)
(plus:SI (match_dup 0)
(match_operand:SI 1 "const_int_operand" "")))]
""
[(set (match_dup 0)
(plus:SI (reg:SI SP_REGNUM) (match_dup 1)))])
;; XMOVEI AC1,OFFSET1(17)
;; ADDI AC1,OFFSET2 -> XMOVEI AC1,OFFSET1+OFFSET2(17)
(define_peephole2
[(set (match_operand:SI 0 "register_operand" "")
(plus:SI (reg:SI SP_REGNUM)
(match_operand:SI 1 "const_int_operand" "")))
(set (match_dup 0)
(plus:SI (match_dup 0)
(match_operand:SI 2 "const_int_operand" "")))]
""
[(set (match_dup 0)
(plus:SI (reg:SI SP_REGNUM) (match_dup 3)))]
"operands[3] = gen_int_mode (INTVAL (operands[1]) + INTVAL (operands[2]),
Pmode);")
;; AOS m
;; MOVE a,m -> AOS a,m
(define_peephole2
[(set (match_operand:SI 0 "reg_or_mem_operand" "")
(plus:SI (match_dup 0)
(const_int 1)))
(set (match_operand:SI 1 "register_operand" "")
(match_dup 0))]
"REGNO (operands[1]) != 0"
[(parallel
[(set (match_dup 0)
(plus:SI (match_dup 0) (const_int 1)))
(set (match_dup 1)
(plus:SI (match_dup 0) (const_int 1)))])])
;; SOS m
;; MOVE a,m -> SOS a,m
(define_peephole2
[(set (match_operand:SI 0 "reg_or_mem_operand" "")
(plus:SI (match_dup 0)
(const_int -1)))
(set (match_operand:SI 1 "register_operand" "")
(match_dup 0))]
"REGNO (operands[1]) != 0"
[(parallel
[(set (match_dup 0)
(plus:SI (match_dup 0) (const_int -1)))
(set (match_dup 1)
(plus:SI (match_dup 0) (const_int -1)))])])
;; AOS a,m
;; CAILE a,0 -> AOSLE a,m
;; MOVEI a,0 MOVEI a,0
(define_peephole
[(parallel [(set (match_operand:SI 0 "memory_operand" "")
(plus:SI (match_dup 0) (const_int 1)))
(set (match_operand:SI 1 "register_operand" "")
(plus:SI (match_dup 0) (const_int 1)))])
(set (match_dup 1)
(smin:SI (match_dup 1) (match_operand 2 "const_int_operand" "")))]
"REGNO (operands[1]) != 0
&& (INTVAL (operands[2]) >= -1 || INTVAL (operands[2]) <= 1)"
{
if (INTVAL (operands[2]) == 0)
return "aosle %1,%0\;%_movei %1,0";
else if (INTVAL (operands[2]) == 1)
return "aosle %1,%0\;%_movei %1,1";
else
return "aosl %1,%0\;%_seto %1,";
})
;; SOS a,m
;; CAILE a,0 -> SOSLE a,m
;; MOVEI a,0 MOVEI a,0
(define_peephole
[(parallel [(set (match_operand:SI 0 "memory_operand" "")
(plus:SI (match_dup 0) (const_int -1)))
(set (match_operand:SI 1 "register_operand" "")
(plus:SI (match_dup 0) (const_int -1)))])
(set (match_dup 1)
(smin:SI (match_dup 1) (match_operand 2 "const_int_operand" "")))]
"REGNO (operands[1]) != 0
&& (INTVAL (operands[2]) >= -1 || INTVAL (operands[2]) <= 1)"
{
if (INTVAL (operands[2]) == 0)
return "sosle %1,%0\;%_movei %1,0";
else if (INTVAL (operands[2]) == 1)
return "sosle %1,%0\;%_movei %1,1";
else
return "sosl %1,%0\;%_seto %1,";
})
;; AOS a,m
;; CAIGE a,0 -> AOSGE a,m
;; MOVEI a,0 MOVEI a,0
(define_peephole
[(parallel [(set (match_operand:SI 0 "memory_operand" "")
(plus:SI (match_dup 0) (const_int 1)))
(set (match_operand:SI 1 "register_operand" "")
(plus:SI (match_dup 0) (const_int 1)))])
(set (match_dup 1)
(smax:SI (match_dup 1) (match_operand 2 "const_int_operand" "")))]
"REGNO (operands[1]) != 0
&& (INTVAL (operands[2]) >= -1 || INTVAL (operands[2]) <= 1)"
{
if (INTVAL (operands[2]) == 0)
return "aosge %1,%0\;%_movei %1,0";
else if (INTVAL (operands[2]) == 1)
return "aosg %1,%0\;%_movei %1,1";
else
return "aosge %1,%0\;%_seto %1,";
})
;; SOS a,m
;; CAIGE a,0 -> SOSGE a,m
;; MOVEI a,0 MOVEI a,0
(define_peephole
[(parallel [(set (match_operand:SI 0 "memory_operand" "")
(plus:SI (match_dup 0) (const_int -1)))
(set (match_operand:SI 1 "register_operand" "")
(plus:SI (match_dup 0) (const_int -1)))])
(set (match_dup 1)
(smax:SI (match_dup 1) (match_operand 2 "const_int_operand" "")))]
"REGNO (operands[1]) != 0
&& (INTVAL (operands[2]) >= -1 || INTVAL (operands[2]) <= 1)"
{
if (INTVAL (operands[2]) == 0)
return "sosge %1,%0\;%_movei %1,0";
else if (INTVAL (operands[2]) == 1)
return "sosg %1,%0\;%_movei %1,1";
else
return "sosge %1,%0\;%_seto %1,";
})
;; AOS m
;; SKIPx m -> AOSx m
(define_peephole2
[(set (match_operand:SI 0 "reg_or_mem_operand" "")
(plus:SI (match_dup 0)
(const_int 1)))
(set (pc)
(if_then_else
(match_operator 2 "pdp10_comparison_operator"
[(match_dup 0)
(const_int 0)])
(label_ref (match_operand 1 "" ""))
(pc)))]
""
[(parallel
[(set (pc)
(if_then_else
(match_op_dup 2
[(plus:SI (match_dup 0) (const_int 1))
(const_int 0)])
(label_ref (match_dup 1))
(pc)))
(set (match_dup 0)
(plus:SI (match_dup 0) (const_int 1)))])])
;; SOS m
;; SKIPx m -> SOSx m
(define_peephole2
[(set (match_operand:SI 0 "reg_or_mem_operand" "")
(plus:SI (match_dup 0)
(const_int -1)))
(set (pc)
(if_then_else
(match_operator 2 "pdp10_comparison_operator"
[(match_dup 0)
(const_int 0)])
(label_ref (match_operand 1 "" ""))
(pc)))]
""
[(parallel
[(set (pc)
(if_then_else
(match_op_dup 2
[(plus:SI (match_dup 0) (const_int -1))
(const_int 0)])
(label_ref (match_dup 1))
(pc)))
(set (match_dup 0)
(plus:SI (match_dup 0) (const_int -1)))])])
;; AOS m
;; SKIPx a,m -> AOSx a,m
(define_peephole2
[(set (match_operand:SI 0 "reg_or_mem_operand" "")
(plus:SI (match_dup 0)
(const_int 1)))
(parallel
[(set (pc)
(if_then_else
(match_operator 3 "pdp10_comparison_operator"
[(match_dup 0)
(const_int 0)])
(label_ref (match_operand 1 "" ""))
(pc)))
(set (match_operand:SI 2 "register_operand" "")
(match_dup 0))])]
"REGNO (operands[2]) != 0"
[(parallel
[(set (pc)
(if_then_else
(match_op_dup 3
[(plus:SI (match_dup 0) (const_int 1))
(const_int 0)])
(label_ref (match_dup 1))
(pc)))
(set (match_dup 0)
(plus:SI (match_dup 0) (const_int 1)))
(set (match_dup 2)
(plus:SI (match_dup 0) (const_int 1)))])])
;; SOS m
;; SKIPx a,m -> SOSx a,m
(define_peephole2
[(set (match_operand:SI 0 "reg_or_mem_operand" "")
(plus:SI (match_dup 0)
(const_int -1)))
(parallel
[(set (pc)
(if_then_else
(match_operator 3 "pdp10_comparison_operator"
[(match_dup 0)
(const_int 0)])
(label_ref (match_operand 1 "" ""))
(pc)))
(set (match_operand:SI 2 "register_operand" "")
(match_dup 0))])]
"REGNO (operands[2]) != 0"
[(parallel
[(set (pc)
(if_then_else
(match_op_dup 3
[(plus:SI (match_dup 0) (const_int -1))
(const_int 0)])
(label_ref (match_dup 1))
(pc)))
(set (match_dup 0)
(plus:SI (match_dup 0) (const_int -1)))
(set (match_dup 2)
(plus:SI (match_dup 0) (const_int -1)))])])
;; ADDI a,1
;; JRST m -> AOJA a,m
;; The traditional peephole is needed to detect sequences after basic
;; block reordering. peephole2 is run before that.
(define_peephole2
[(set (match_operand:SI 0 "register_operand" "")
(plus:SI (match_dup 0)
(const_int 1)))
(set (pc)
(label_ref (match_operand 1 "" "")))]
""
[(parallel
[(set (pc)
(label_ref (match_dup 1)))
(set (match_dup 0)
(plus:SI (match_dup 0)
(const_int 1)))])])
(define_peephole
[(set (match_operand:SI 0 "register_operand" "")
(plus:SI (match_dup 0)
(const_int 1)))
(set (pc)
(label_ref (match_operand 1 "" "")))]
""
"aoja %0,%l1")
;; SUBI a,1
;; JRST m -> SOJA a,m
;; The traditional peephole is needed to detect sequences after basic
;; block reordering. peephole2 is run before that.
(define_peephole2
[(set (match_operand:SI 0 "register_operand" "")
(plus:SI (match_dup 0)
(const_int -1)))
(set (pc)
(label_ref (match_operand 1 "" "")))]
""
[(parallel
[(set (pc)
(label_ref (match_dup 1)))
(set (match_dup 0)
(plus:SI (match_dup 0)
(const_int -1)))])])
(define_peephole
[(set (match_operand:SI 0 "register_operand" "")
(plus:SI (match_dup 0)
(const_int -1)))
(set (pc)
(label_ref (match_operand 1 "" "")))]
""
"soja %0,%l1")
;; AOS m1
;; JRST m2 -> AOSA m1,m2 (if possible)
;; TODO.
;; SOS m1
;; JRST m2 -> SOSA m1,m2 (if possible)
;; TODO.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Miscellaneous
;; UNSPEC_VOLATILE is considered to use and clobber all hard registers
;; and all of memory. This blocks insns from being moved across this
;; point.
(define_insn "blockage"
[(unspec_volatile [(const_int 0)] VUNSPEC_BLOCKAGE)]
""
""
[(set_attr "length" "0")])
(define_insn "*movqi_subreg"
[(set (match_operand:QI 0 "register_operand" "=r")
(subreg:QI (match_operand:SI 1 "register_operand" "r") 3))]
""
"move %0,%1%; (set (reg:QI %0) (subreg:QI (reg:SI %1) 3)")
(define_insn ""
[(set (subreg:QI (match_operand:SI 0 "register_operand" "=r") 3)
(match_operand:QI 1 "register_operand" "r"))]
""
"move %0,%1%; (set (subreg:QI (reg:SI %0) 3) (reg:QI %1)")
(define_insn ""
[(set (match_operand:QI 0 "register_operand" "=r")
(subreg:QI (match_operand:SI 1 "register_operand" "0") 0))]
""
"lsh %0,-33%; (set (reg:QI %0) (subreg:QI (reg:SI %1) 0))")
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
(subreg:HI (match_operand:SI 1 "register_operand" "r") 0))]
""
"hlrz %0,%1%; (set (reg:HI %0) (subreg:HI (reg:SI %1) 0))")
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
(subreg:HI (match_operand:SI 1 "register_operand" "r") 2))]
""
"hrrz %0,%1%; (set (reg:HI %0) (subreg:HI (reg:SI %1) 2))")
(define_insn ""
[(set (match_operand:HI 0 "register_operand" "=r")
(subreg:HI (zero_extract:SI (match_operand:SI 1 "memory_operand" "m")
(const_int 18)
(const_int 18))
0))]
""
"hrrz %0,%1%; (set (reg:HI %0) (subreg:HI (zero_extr:SI %1 18 18) 0))")
(define_insn ""
[(set (match_operand:QI 0 "register_operand" "=r")
(subreg:QI (zero_extract:SI (match_operand:SI 1 "memory_operand" "m")
(const_int 9)
(const_int 27))
0))]
""
;; FIXME: will this do?
"move %0,%1"
[(set_attr "length" "3")])
;; Only used in KA10 expansion of FIX.
(define_insn "TSC"
[(set (match_operand:SI 0 "register_operand" "=r")
(xor:SI
(match_dup 0)
(ior:SI
(ashift:SI (match_operand:SI 1 "reg_or_mem_operand" "rm")
(const_int 18))
(lshiftrt:SI (match_dup 1) (const_int 18)))))]
""
"tsc %0,%1")
(define_insn ""
[(set (match_operand:SI 0 "register_operand" "=r")
(ashiftrt:SI (match_operand:SI 1 "memory_operand" "m")
(const_int 27)))]
""
"move %0,%1\;ash %0,-33"
[(set_attr "length" "2")])
(define_insn ""
[(set (match_operand:QI 0 "register_operand" "=r")
(subreg:QI (zero_extract:SI (match_operand:SI 1 "memory_operand" "m")
(const_int 9)
(const_int 0))
3))]
""
{
rtx ops[4];
ops[0] = operands[0];
ops[1] = operands[1];
ops[2] = GEN_INT (9);
ops[3] = GEN_INT (0);
if (get_attr_length (insn) == 1)
output_asm_insn (pdp10_output_extzv (insn, ops), ops);
else
output_asm_insn (pdp10_output_extzv_sequence (ops), ops);
return "";
}
[(set (attr "length")
(if_then_else (ne (symbol_ref "TARGET_LARGE") (const_int 0))
(const_int 1)
(const_int 2)))])
(define_insn ""
[(set (match_operand:QI 0 "register_operand" "=r")
(subreg:QI (zero_extract:SI (match_operand:SI 1 "memory_operand" "m")
(const_int 9)
(const_int 9))
3))]
""
{
rtx ops[4];
ops[0] = operands[0];
ops[1] = operands[1];
ops[2] = GEN_INT (9);
ops[3] = GEN_INT (9);
output_asm_insn (pdp10_output_extzv (insn, ops), ops);
return "";
})