16ca2c52aSchristos; OpenRISC 1000 architecture.  -*- Scheme -*-
2*184b2d41Schristos; Copyright 2000-2019 Free Software Foundation, Inc.
36ca2c52aSchristos; Contributed by Peter Gavin, pgavin@gmail.com
4*184b2d41Schristos; Modified by Andrey Bacherov, avbacherov@opencores.org
56ca2c52aSchristos;
66ca2c52aSchristos; This program is free software; you can redistribute it and/or modify
76ca2c52aSchristos; it under the terms of the GNU General Public License as published by
86ca2c52aSchristos; the Free Software Foundation; either version 3 of the License, or
96ca2c52aSchristos; (at your option) any later version.
106ca2c52aSchristos;
116ca2c52aSchristos; This program is distributed in the hope that it will be useful,
126ca2c52aSchristos; but WITHOUT ANY WARRANTY; without even the implied warranty of
136ca2c52aSchristos; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
146ca2c52aSchristos; GNU General Public License for more details.
156ca2c52aSchristos;
166ca2c52aSchristos; You should have received a copy of the GNU General Public License
176ca2c52aSchristos; along with this program; if not, see <http://www.gnu.org/licenses/>
186ca2c52aSchristos
196ca2c52aSchristos; Initial ORFPX32 instruction set
206ca2c52aSchristos
216ca2c52aSchristos; I'm not sure how CGEN handles rounding in FP operations, except for
226ca2c52aSchristos; in conversions to/from integers.  So lf.add, lf.sub, lf.mul, and
236ca2c52aSchristos; lf.div do not round according to the FPCSR RM field.
246ca2c52aSchristos; NaN, overflow, and underflow are not yet handled either.
256ca2c52aSchristos
266ca2c52aSchristos(define-normal-insn-enum insn-opcode-float-regreg
276ca2c52aSchristos  "floating point reg/reg insn opcode enums" ()
286ca2c52aSchristos  OPC_FLOAT_REGREG_ f-op-7-8
296ca2c52aSchristos  (("ADD_S"  #x00)
306ca2c52aSchristos   ("SUB_S"  #x01)
316ca2c52aSchristos   ("MUL_S"  #x02)
326ca2c52aSchristos   ("DIV_S"  #x03)
336ca2c52aSchristos   ("ITOF_S" #x04)
346ca2c52aSchristos   ("FTOI_S" #x05)
356ca2c52aSchristos   ("REM_S"  #x06)
366ca2c52aSchristos   ("MADD_S" #x07)
376ca2c52aSchristos   ("SFEQ_S" #x08)
386ca2c52aSchristos   ("SFNE_S" #x09)
396ca2c52aSchristos   ("SFGT_S" #x0a)
406ca2c52aSchristos   ("SFGE_S" #x0b)
416ca2c52aSchristos   ("SFLT_S" #x0c)
426ca2c52aSchristos   ("SFLE_S" #x0d)
436ca2c52aSchristos   ("ADD_D"  #x10)
446ca2c52aSchristos   ("SUB_D"  #x11)
456ca2c52aSchristos   ("MUL_D"  #x12)
466ca2c52aSchristos   ("DIV_D"  #x13)
476ca2c52aSchristos   ("ITOF_D" #x14)
486ca2c52aSchristos   ("FTOI_D" #x15)
496ca2c52aSchristos   ("REM_D"  #x16)
506ca2c52aSchristos   ("MADD_D" #x17)
516ca2c52aSchristos   ("SFEQ_D" #x18)
526ca2c52aSchristos   ("SFNE_D" #x19)
536ca2c52aSchristos   ("SFGT_D" #x1a)
546ca2c52aSchristos   ("SFGE_D" #x1b)
556ca2c52aSchristos   ("SFLT_D" #x1c)
566ca2c52aSchristos   ("SFLE_D" #x1d)
57*184b2d41Schristos   ("SFUEQ_S" #x28)
58*184b2d41Schristos   ("SFUNE_S" #x29)
59*184b2d41Schristos   ("SFUGT_S" #x2a)
60*184b2d41Schristos   ("SFUGE_S" #x2b)
61*184b2d41Schristos   ("SFULT_S" #x2c)
62*184b2d41Schristos   ("SFULE_S" #x2d)
63*184b2d41Schristos   ("SFUN_S" #x2e)
64*184b2d41Schristos   ("SFUEQ_D" #x38)
65*184b2d41Schristos   ("SFUNE_D" #x39)
66*184b2d41Schristos   ("SFUGT_D" #x3a)
67*184b2d41Schristos   ("SFUGE_D" #x3b)
68*184b2d41Schristos   ("SFULT_D" #x3c)
69*184b2d41Schristos   ("SFULE_D" #x3d)
70*184b2d41Schristos   ("SFUN_D" #x3e)
716ca2c52aSchristos   ("CUST1_S" #xd0)
726ca2c52aSchristos   ("CUST1_D" #xe0)
736ca2c52aSchristos   )
746ca2c52aSchristos  )
756ca2c52aSchristos
76*184b2d41Schristos; Register offset flags, if set offset is 2 otherwise offset is 1
77*184b2d41Schristos(dnf f-rdoff-10-1   "destination register pair offset flag" ((MACH ORFPX64A32-MACHS)) 10 1)
78*184b2d41Schristos(dnf f-raoff-9-1    "source register A pair offset flag"    ((MACH ORFPX64A32-MACHS)) 9 1)
79*184b2d41Schristos(dnf f-rboff-8-1    "source register B pair offset flag"    ((MACH ORFPX64A32-MACHS)) 8 1)
806ca2c52aSchristos
81*184b2d41Schristos(dsh h-roff1        "1-bit offset flag"                     () (register BI))
82*184b2d41Schristos
83*184b2d41Schristos(dnop rDSF "destination register (single floating point mode)" ((MACH ORFPX32-MACHS)) h-fsr f-r1)
84*184b2d41Schristos(dnop rASF "source register A (single floating point mode)"    ((MACH ORFPX32-MACHS)) h-fsr f-r2)
85*184b2d41Schristos(dnop rBSF "source register B (single floating point mode)"    ((MACH ORFPX32-MACHS)) h-fsr f-r3)
86*184b2d41Schristos
87*184b2d41Schristos(define-pmacro (double-field-and-ops mnemonic reg offbit op-comment)
88*184b2d41Schristos  (begin
89*184b2d41Schristos    (define-multi-ifield
90*184b2d41Schristos      (name (.sym "f-r" (.downcase mnemonic) "d32"))
91*184b2d41Schristos      (comment op-comment)
92*184b2d41Schristos      (attrs (MACH ORFPX64A32-MACHS))
93*184b2d41Schristos      (mode SI)
94*184b2d41Schristos      (subfields reg offbit)
95*184b2d41Schristos      ; From the multi-ifield insert the bits into subfields
96*184b2d41Schristos      (insert (sequence
97*184b2d41Schristos		()
98*184b2d41Schristos		(set (ifield reg)
99*184b2d41Schristos		  (and (ifield (.sym "f-r" (.downcase mnemonic) "d32"))
100*184b2d41Schristos		       (const #x1f))
101*184b2d41Schristos		  )
102*184b2d41Schristos		(set (ifield offbit)
103*184b2d41Schristos		  (and (sra (ifield (.sym "f-r" (.downcase mnemonic) "d32"))
104*184b2d41Schristos		            (const 5))
105*184b2d41Schristos		       (const 1))
106*184b2d41Schristos		  )
107*184b2d41Schristos		)
108*184b2d41Schristos	)
109*184b2d41Schristos      ; Extract the multi-ifield from the subfield bits
110*184b2d41Schristos      (extract
111*184b2d41Schristos	       (set (ifield (.sym "f-r" (.downcase mnemonic) "d32"))
112*184b2d41Schristos		    (or (ifield reg)
113*184b2d41Schristos			(sll (ifield offbit)
114*184b2d41Schristos			     (const 5)))
115*184b2d41Schristos		 )
116*184b2d41Schristos        )
117*184b2d41Schristos      )
118*184b2d41Schristos    (define-operand
119*184b2d41Schristos      (name (.sym "r" (.upcase mnemonic) "D32F"))
120*184b2d41Schristos      (comment (.str op-comment " (double floating point pair)"))
121*184b2d41Schristos      (attrs (MACH ORFPX64A32-MACHS))
122*184b2d41Schristos      (type h-fd32r)
123*184b2d41Schristos      (index (.sym "f-r" (.downcase mnemonic) "d32"))
124*184b2d41Schristos      (handlers (parse "regpair") (print "regpair"))
125*184b2d41Schristos      )
126*184b2d41Schristos    (define-operand
127*184b2d41Schristos      (name (.sym "r" (.upcase mnemonic) "DI"))
128*184b2d41Schristos      (comment (.str op-comment " (double integer pair)"))
129*184b2d41Schristos      (attrs (MACH ORFPX64A32-MACHS))
130*184b2d41Schristos      (type h-i64r)
131*184b2d41Schristos      (index (.sym "f-r" (.downcase mnemonic) "d32"))
132*184b2d41Schristos      (handlers (parse "regpair") (print "regpair"))
133*184b2d41Schristos      )
134*184b2d41Schristos    )
135*184b2d41Schristos  )
136*184b2d41Schristos
137*184b2d41Schristos(double-field-and-ops D f-r1 f-rdoff-10-1 "destination register")
138*184b2d41Schristos(double-field-and-ops A f-r2 f-raoff-9-1  "source register A")
139*184b2d41Schristos(double-field-and-ops B f-r3 f-rboff-8-1  "source register B")
1406ca2c52aSchristos
1416ca2c52aSchristos(define-pmacro (float-regreg-insn mnemonic)
1426ca2c52aSchristos  (begin
1436ca2c52aSchristos    (dni (.sym lf- mnemonic -s)
1446ca2c52aSchristos         (.str "lf." mnemonic ".s reg/reg/reg")
145*184b2d41Schristos         ((MACH ORFPX32-MACHS))
1466ca2c52aSchristos         (.str "lf." mnemonic ".s $rDSF,$rASF,$rBSF")
1476ca2c52aSchristos         (+ OPC_FLOAT rDSF rASF rBSF (f-resv-10-3 0) (.sym OPC_FLOAT_REGREG_ (.upcase mnemonic) _S))
1486ca2c52aSchristos         (set SF rDSF (mnemonic SF rASF rBSF))
1496ca2c52aSchristos         ()
1506ca2c52aSchristos         )
151*184b2d41Schristos    (dni (.sym lf- mnemonic -d32)
152*184b2d41Schristos         (.str "lf." mnemonic ".d regpair/regpair/regpair")
153*184b2d41Schristos         ((MACH ORFPX64A32-MACHS))
154*184b2d41Schristos         (.str "lf." mnemonic ".d $rDD32F,$rAD32F,$rBD32F")
155*184b2d41Schristos         (+ OPC_FLOAT rDD32F rAD32F rBD32F (.sym OPC_FLOAT_REGREG_ (.upcase mnemonic) _D))
156*184b2d41Schristos         (set DF rDD32F (mnemonic DF rAD32F rBD32F))
1576ca2c52aSchristos         ()
1586ca2c52aSchristos         )
1596ca2c52aSchristos    )
1606ca2c52aSchristos  )
1616ca2c52aSchristos
1626ca2c52aSchristos(float-regreg-insn add)
1636ca2c52aSchristos(float-regreg-insn sub)
1646ca2c52aSchristos(float-regreg-insn mul)
1656ca2c52aSchristos(float-regreg-insn div)
1666ca2c52aSchristos
1676ca2c52aSchristos(dni lf-rem-s
1686ca2c52aSchristos     "lf.rem.s reg/reg/reg"
169*184b2d41Schristos     ((MACH ORFPX32-MACHS))
1706ca2c52aSchristos     "lf.rem.s $rDSF,$rASF,$rBSF"
1716ca2c52aSchristos     (+ OPC_FLOAT rDSF rASF rBSF (f-resv-10-3 0) OPC_FLOAT_REGREG_REM_S)
1726ca2c52aSchristos     (set SF rDSF (rem SF rASF rBSF))
1736ca2c52aSchristos     ()
1746ca2c52aSchristos     )
175*184b2d41Schristos
176*184b2d41Schristos(dni lf-rem-d32
177*184b2d41Schristos     "lf.rem.d regpair/regpair/regpair"
178*184b2d41Schristos     ((MACH ORFPX64A32-MACHS))
179*184b2d41Schristos     "lf.rem.d $rDD32F,$rAD32F,$rBD32F"
180*184b2d41Schristos     (+ OPC_FLOAT rDD32F rAD32F rBD32F OPC_FLOAT_REGREG_REM_D)
181*184b2d41Schristos     (set DF rDD32F (rem DF rAD32F rBD32F))
1826ca2c52aSchristos     ()
1836ca2c52aSchristos     )
1846ca2c52aSchristos
1856ca2c52aSchristos(define-pmacro (get-rounding-mode)
1866ca2c52aSchristos  (case INT sys-fpcsr-rm
1876ca2c52aSchristos        ((0) 1) ; TIES-TO-EVEN -- I'm assuming this is what is meant by "round to nearest"
1886ca2c52aSchristos        ((1) 3) ; TOWARD-ZERO
1896ca2c52aSchristos        ((2) 4) ; TOWARD-POSITIVE
1906ca2c52aSchristos        (else 5) ; TOWARD-NEGATIVE
1916ca2c52aSchristos        )
1926ca2c52aSchristos  )
1936ca2c52aSchristos
1946ca2c52aSchristos(dni lf-itof-s
1956ca2c52aSchristos     "lf.itof.s reg/reg"
196*184b2d41Schristos     ((MACH ORFPX32-MACHS))
1976ca2c52aSchristos     "lf.itof.s $rDSF,$rA"
1986ca2c52aSchristos     (+ OPC_FLOAT rDSF rA (f-r3 0) (f-resv-10-3 0) OPC_FLOAT_REGREG_ITOF_S)
1996ca2c52aSchristos     (set SF rDSF (float SF (get-rounding-mode) (trunc SI rA)))
2006ca2c52aSchristos     ()
2016ca2c52aSchristos     )
202*184b2d41Schristos
203*184b2d41Schristos(dni lf-itof-d32
204*184b2d41Schristos     "lf.itof.d regpair/regpair"
205*184b2d41Schristos     ((MACH ORFPX64A32-MACHS))
206*184b2d41Schristos     "lf.itof.d $rDD32F,$rADI"
207*184b2d41Schristos     (+ OPC_FLOAT rDD32F rADI (f-r3 0) (f-resv-8-1 0) OPC_FLOAT_REGREG_ITOF_D)
208*184b2d41Schristos     (set DF rDD32F (float DF (get-rounding-mode) rADI))
2096ca2c52aSchristos     ()
2106ca2c52aSchristos     )
2116ca2c52aSchristos
2126ca2c52aSchristos(dni lf-ftoi-s
2136ca2c52aSchristos     "lf.ftoi.s reg/reg"
214*184b2d41Schristos     ((MACH ORFPX32-MACHS))
2156ca2c52aSchristos     "lf.ftoi.s $rD,$rASF"
2166ca2c52aSchristos     (+ OPC_FLOAT rD rASF (f-r3 0) (f-resv-10-3 0) OPC_FLOAT_REGREG_FTOI_S)
2176ca2c52aSchristos     (set WI rD (ext WI (fix SI (get-rounding-mode) rASF)))
2186ca2c52aSchristos     ()
2196ca2c52aSchristos     )
2206ca2c52aSchristos
221*184b2d41Schristos(dni lf-ftoi-d32
222*184b2d41Schristos     "lf.ftoi.d regpair/regpair"
223*184b2d41Schristos     ((MACH ORFPX64A32-MACHS))
224*184b2d41Schristos     "lf.ftoi.d $rDDI,$rAD32F"
225*184b2d41Schristos     (+ OPC_FLOAT rDDI rAD32F (f-r3 0) (f-resv-8-1 0) OPC_FLOAT_REGREG_FTOI_D)
226*184b2d41Schristos     (set DI rDDI (fix DI (get-rounding-mode) rAD32F))
2276ca2c52aSchristos     ()
2286ca2c52aSchristos     )
2296ca2c52aSchristos
230*184b2d41Schristos(define-pmacro (float-setflag-insn-base mnemonic rtx-mnemonic symantics)
2316ca2c52aSchristos  (begin
232*184b2d41Schristos    (dni (.sym lf-sf mnemonic -s)
2336ca2c52aSchristos         (.str "lf.sf" mnemonic ".s reg/reg")
234*184b2d41Schristos         ((MACH ORFPX32-MACHS))
2356ca2c52aSchristos         (.str "lf.sf" mnemonic ".s $rASF,$rBSF")
2366ca2c52aSchristos         (+ OPC_FLOAT (f-r1 0) rASF rBSF (f-resv-10-3 0) (.sym OPC_FLOAT_REGREG_SF (.upcase mnemonic) _S))
237*184b2d41Schristos         (symantics rtx-mnemonic SF rASF rBSF)
2386ca2c52aSchristos         ()
2396ca2c52aSchristos         )
240*184b2d41Schristos    (dni (.sym lf-sf mnemonic -d32)
241*184b2d41Schristos         (.str "lf.sf" mnemonic ".d regpair/regpair")
242*184b2d41Schristos         ((MACH ORFPX64A32-MACHS))
243*184b2d41Schristos         (.str "lf.sf" mnemonic ".d $rAD32F,$rBD32F")
244*184b2d41Schristos         (+ OPC_FLOAT (f-r1 0) rAD32F rBD32F (f-resv-10-1 0) (.sym OPC_FLOAT_REGREG_SF (.upcase mnemonic) _D))
245*184b2d41Schristos         (symantics rtx-mnemonic DF rAD32F rBD32F)
2466ca2c52aSchristos         ()
2476ca2c52aSchristos         )
2486ca2c52aSchristos    )
2496ca2c52aSchristos  )
2506ca2c52aSchristos
251*184b2d41Schristos(define-pmacro (float-setflag-symantics mnemonic mode r1 r2)
252*184b2d41Schristos  (set BI sys-sr-f (mnemonic mode r1 r2)))
253*184b2d41Schristos
254*184b2d41Schristos(define-pmacro (float-setflag-insn mnemonic)
255*184b2d41Schristos  (float-setflag-insn-base mnemonic mnemonic float-setflag-symantics))
256*184b2d41Schristos
257*184b2d41Schristos(define-pmacro (float-setflag-unordered-cmp-symantics mnemonic mode r1 r2)
258*184b2d41Schristos  (set BI sys-sr-f (or (unordered mode r1 r2)
259*184b2d41Schristos                       (mnemonic mode r1 r2))))
260*184b2d41Schristos
261*184b2d41Schristos(define-pmacro (float-setflag-unordered-symantics mnemonic mode r1 r2)
262*184b2d41Schristos  (set BI sys-sr-f (unordered mode r1 r2)))
263*184b2d41Schristos
264*184b2d41Schristos(define-pmacro (float-setflag-unordered-insn mnemonic)
265*184b2d41Schristos  (float-setflag-insn-base (.str "u" mnemonic)
266*184b2d41Schristos                           mnemonic
267*184b2d41Schristos                           float-setflag-unordered-cmp-symantics))
268*184b2d41Schristos
2696ca2c52aSchristos(float-setflag-insn eq)
2706ca2c52aSchristos(float-setflag-insn ne)
2716ca2c52aSchristos(float-setflag-insn ge)
2726ca2c52aSchristos(float-setflag-insn gt)
2736ca2c52aSchristos(float-setflag-insn lt)
2746ca2c52aSchristos(float-setflag-insn le)
275*184b2d41Schristos(float-setflag-unordered-insn eq)
276*184b2d41Schristos(float-setflag-unordered-insn ne)
277*184b2d41Schristos(float-setflag-unordered-insn gt)
278*184b2d41Schristos(float-setflag-unordered-insn ge)
279*184b2d41Schristos(float-setflag-unordered-insn lt)
280*184b2d41Schristos(float-setflag-unordered-insn le)
281*184b2d41Schristos(float-setflag-insn-base un () float-setflag-unordered-symantics)
2826ca2c52aSchristos
2836ca2c52aSchristos(dni lf-madd-s
2846ca2c52aSchristos     "lf.madd.s reg/reg/reg"
285*184b2d41Schristos     ((MACH ORFPX32-MACHS))
2866ca2c52aSchristos     "lf.madd.s $rDSF,$rASF,$rBSF"
2876ca2c52aSchristos     (+ OPC_FLOAT rDSF rASF rBSF (f-resv-10-3 0) OPC_FLOAT_REGREG_MADD_S)
2886ca2c52aSchristos     (set SF rDSF (add SF (mul SF rASF rBSF) rDSF))
2896ca2c52aSchristos     ()
2906ca2c52aSchristos     )
291*184b2d41Schristos
292*184b2d41Schristos(dni lf-madd-d32
293*184b2d41Schristos     "lf.madd.d regpair/regpair/regpair"
294*184b2d41Schristos     ((MACH ORFPX64A32-MACHS))
295*184b2d41Schristos     "lf.madd.d $rDD32F,$rAD32F,$rBD32F"
296*184b2d41Schristos     (+ OPC_FLOAT rDD32F rAD32F rBD32F OPC_FLOAT_REGREG_MADD_D)
297*184b2d41Schristos     (set DF rDD32F (add DF (mul DF rAD32F rBD32F) rDD32F))
2986ca2c52aSchristos     ()
2996ca2c52aSchristos     )
3006ca2c52aSchristos
3016ca2c52aSchristos(define-pmacro (float-cust-insn cust-num)
3026ca2c52aSchristos  (begin
3036ca2c52aSchristos    (dni (.sym "lf-cust" cust-num "-s")
3046ca2c52aSchristos         (.str "lf.cust" cust-num ".s")
305*184b2d41Schristos         ((MACH ORFPX32-MACHS))
3066ca2c52aSchristos         (.str "lf.cust" cust-num ".s $rASF,$rBSF")
3076ca2c52aSchristos         (+ OPC_FLOAT (f-resv-25-5 0) rASF rBSF (f-resv-10-3 0) (.sym "OPC_FLOAT_REGREG_CUST" cust-num "_S"))
3086ca2c52aSchristos         (nop)
3096ca2c52aSchristos         ()
3106ca2c52aSchristos         )
311*184b2d41Schristos    (dni (.sym "lf-cust" cust-num "-d32")
3126ca2c52aSchristos         (.str "lf.cust" cust-num ".d")
313*184b2d41Schristos         ((MACH ORFPX64A32-MACHS))
3146ca2c52aSchristos         (.str "lf.cust" cust-num ".d")
315*184b2d41Schristos         (+ OPC_FLOAT (f-resv-25-5 0) rAD32F rBD32F (f-resv-10-1 0) (.sym "OPC_FLOAT_REGREG_CUST" cust-num "_D"))
3166ca2c52aSchristos         (nop)
3176ca2c52aSchristos         ()
3186ca2c52aSchristos         )
3196ca2c52aSchristos    )
3206ca2c52aSchristos  )
3216ca2c52aSchristos
3226ca2c52aSchristos(float-cust-insn "1")
323