mirror of
https://github.com/KevinMidboe/linguist.git
synced 2025-10-29 17:50:22 +00:00
6666 lines
198 KiB
Markdown
6666 lines
198 KiB
Markdown
;;- 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 "";
|
||
})
|