xref: /netbsd-src/external/gpl3/binutils/dist/cpu/or1korfpx.cpu (revision cef8759bd76c1b621f8eab8faa6f208faabc2e15)
1; OpenRISC 1000 architecture.  -*- Scheme -*-
2; Copyright 2000-2019 Free Software Foundation, Inc.
3; Contributed by Peter Gavin, pgavin@gmail.com
4; Modified by Andrey Bacherov, avbacherov@opencores.org
5;
6; This program is free software; you can redistribute it and/or modify
7; it under the terms of the GNU General Public License as published by
8; the Free Software Foundation; either version 3 of the License, or
9; (at your option) any later version.
10;
11; This program is distributed in the hope that it will be useful,
12; but WITHOUT ANY WARRANTY; without even the implied warranty of
13; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14; GNU General Public License for more details.
15;
16; You should have received a copy of the GNU General Public License
17; along with this program; if not, see <http://www.gnu.org/licenses/>
18
19; Initial ORFPX32 instruction set
20
21; I'm not sure how CGEN handles rounding in FP operations, except for
22; in conversions to/from integers.  So lf.add, lf.sub, lf.mul, and
23; lf.div do not round according to the FPCSR RM field.
24; NaN, overflow, and underflow are not yet handled either.
25
26(define-normal-insn-enum insn-opcode-float-regreg
27  "floating point reg/reg insn opcode enums" ()
28  OPC_FLOAT_REGREG_ f-op-7-8
29  (("ADD_S"  #x00)
30   ("SUB_S"  #x01)
31   ("MUL_S"  #x02)
32   ("DIV_S"  #x03)
33   ("ITOF_S" #x04)
34   ("FTOI_S" #x05)
35   ("REM_S"  #x06)
36   ("MADD_S" #x07)
37   ("SFEQ_S" #x08)
38   ("SFNE_S" #x09)
39   ("SFGT_S" #x0a)
40   ("SFGE_S" #x0b)
41   ("SFLT_S" #x0c)
42   ("SFLE_S" #x0d)
43   ("ADD_D"  #x10)
44   ("SUB_D"  #x11)
45   ("MUL_D"  #x12)
46   ("DIV_D"  #x13)
47   ("ITOF_D" #x14)
48   ("FTOI_D" #x15)
49   ("REM_D"  #x16)
50   ("MADD_D" #x17)
51   ("SFEQ_D" #x18)
52   ("SFNE_D" #x19)
53   ("SFGT_D" #x1a)
54   ("SFGE_D" #x1b)
55   ("SFLT_D" #x1c)
56   ("SFLE_D" #x1d)
57   ("SFUEQ_S" #x28)
58   ("SFUNE_S" #x29)
59   ("SFUGT_S" #x2a)
60   ("SFUGE_S" #x2b)
61   ("SFULT_S" #x2c)
62   ("SFULE_S" #x2d)
63   ("SFUN_S" #x2e)
64   ("SFUEQ_D" #x38)
65   ("SFUNE_D" #x39)
66   ("SFUGT_D" #x3a)
67   ("SFUGE_D" #x3b)
68   ("SFULT_D" #x3c)
69   ("SFULE_D" #x3d)
70   ("SFUN_D" #x3e)
71   ("CUST1_S" #xd0)
72   ("CUST1_D" #xe0)
73   )
74  )
75
76; Register offset flags, if set offset is 2 otherwise offset is 1
77(dnf f-rdoff-10-1   "destination register pair offset flag" ((MACH ORFPX64A32-MACHS)) 10 1)
78(dnf f-raoff-9-1    "source register A pair offset flag"    ((MACH ORFPX64A32-MACHS)) 9 1)
79(dnf f-rboff-8-1    "source register B pair offset flag"    ((MACH ORFPX64A32-MACHS)) 8 1)
80
81(dsh h-roff1        "1-bit offset flag"                     () (register BI))
82
83(dnop rDSF "destination register (single floating point mode)" ((MACH ORFPX32-MACHS)) h-fsr f-r1)
84(dnop rASF "source register A (single floating point mode)"    ((MACH ORFPX32-MACHS)) h-fsr f-r2)
85(dnop rBSF "source register B (single floating point mode)"    ((MACH ORFPX32-MACHS)) h-fsr f-r3)
86
87(dnop rDDF "or64 destination register (double floating point mode)" ((MACH ORFPX64-MACHS)) h-fdr f-r1)
88(dnop rADF "or64 source register A (double floating point mode)"    ((MACH ORFPX64-MACHS)) h-fdr f-r2)
89(dnop rBDF "or64 source register B (double floating point mode)"    ((MACH ORFPX64-MACHS)) h-fdr f-r3)
90
91(define-pmacro (double-field-and-ops mnemonic reg offbit op-comment)
92  (begin
93    (define-multi-ifield
94      (name (.sym "f-r" (.downcase mnemonic) "d32"))
95      (comment op-comment)
96      (attrs (MACH ORFPX64A32-MACHS))
97      (mode SI)
98      (subfields reg offbit)
99      ; From the multi-ifield insert the bits into subfields
100      (insert (sequence
101		()
102		(set (ifield reg)
103		  (and (ifield (.sym "f-r" (.downcase mnemonic) "d32"))
104		       (const #x1f))
105		  )
106		(set (ifield offbit)
107		  (and (sra (ifield (.sym "f-r" (.downcase mnemonic) "d32"))
108		            (const 5))
109		       (const 1))
110		  )
111		)
112	)
113      ; Extract the multi-ifield from the subfield bits
114      (extract
115	       (set (ifield (.sym "f-r" (.downcase mnemonic) "d32"))
116		    (or (ifield reg)
117			(sll (ifield offbit)
118			     (const 5)))
119		 )
120        )
121      )
122    (define-operand
123      (name (.sym "r" (.upcase mnemonic) "D32F"))
124      (comment (.str op-comment " (double floating point pair)"))
125      (attrs (MACH ORFPX64A32-MACHS))
126      (type h-fd32r)
127      (index (.sym "f-r" (.downcase mnemonic) "d32"))
128      (handlers (parse "regpair") (print "regpair"))
129      )
130    (define-operand
131      (name (.sym "r" (.upcase mnemonic) "DI"))
132      (comment (.str op-comment " (double integer pair)"))
133      (attrs (MACH ORFPX64A32-MACHS))
134      (type h-i64r)
135      (index (.sym "f-r" (.downcase mnemonic) "d32"))
136      (handlers (parse "regpair") (print "regpair"))
137      )
138    )
139  )
140
141(double-field-and-ops D f-r1 f-rdoff-10-1 "destination register")
142(double-field-and-ops A f-r2 f-raoff-9-1  "source register A")
143(double-field-and-ops B f-r3 f-rboff-8-1  "source register B")
144
145(define-pmacro (float-regreg-insn mnemonic)
146  (begin
147    (dni (.sym lf- mnemonic -s)
148         (.str "lf." mnemonic ".s reg/reg/reg")
149         ((MACH ORFPX32-MACHS))
150         (.str "lf." mnemonic ".s $rDSF,$rASF,$rBSF")
151         (+ OPC_FLOAT rDSF rASF rBSF (f-resv-10-3 0) (.sym OPC_FLOAT_REGREG_ (.upcase mnemonic) _S))
152         (set SF rDSF (mnemonic SF rASF rBSF))
153         ()
154         )
155    (dni (.sym lf- mnemonic -d)
156         (.str "lf." mnemonic ".d reg/reg/reg")
157         ((MACH ORFPX64-MACHS))
158         (.str "lf." mnemonic ".d $rDDF,$rADF,$rBDF")
159         (+ OPC_FLOAT rDDF rADF rBDF (f-resv-10-3 0) (.sym OPC_FLOAT_REGREG_ (.upcase mnemonic) _D))
160         (set DF rDDF (mnemonic DF rADF rBDF))
161         ()
162         )
163    (dni (.sym lf- mnemonic -d32)
164         (.str "lf." mnemonic ".d regpair/regpair/regpair")
165         ((MACH ORFPX64A32-MACHS))
166         (.str "lf." mnemonic ".d $rDD32F,$rAD32F,$rBD32F")
167         (+ OPC_FLOAT rDD32F rAD32F rBD32F (.sym OPC_FLOAT_REGREG_ (.upcase mnemonic) _D))
168         (set DF rDD32F (mnemonic DF rAD32F rBD32F))
169         ()
170         )
171    )
172  )
173
174(float-regreg-insn add)
175(float-regreg-insn sub)
176(float-regreg-insn mul)
177(float-regreg-insn div)
178
179(dni lf-rem-s
180     "lf.rem.s reg/reg/reg"
181     ((MACH ORFPX32-MACHS))
182     "lf.rem.s $rDSF,$rASF,$rBSF"
183     (+ OPC_FLOAT rDSF rASF rBSF (f-resv-10-3 0) OPC_FLOAT_REGREG_REM_S)
184     (set SF rDSF (rem SF rASF rBSF))
185     ()
186     )
187
188(dni lf-rem-d
189     "lf.rem.d reg/reg/reg"
190     ((MACH ORFPX64-MACHS))
191     "lf.rem.d $rDDF,$rADF,$rBDF"
192     (+ OPC_FLOAT rDDF rADF rBDF (f-resv-10-3 0) OPC_FLOAT_REGREG_REM_D)
193     (set DF rDDF (rem DF rADF rBDF))
194     ()
195     )
196
197(dni lf-rem-d32
198     "lf.rem.d regpair/regpair/regpair"
199     ((MACH ORFPX64A32-MACHS))
200     "lf.rem.d $rDD32F,$rAD32F,$rBD32F"
201     (+ OPC_FLOAT rDD32F rAD32F rBD32F OPC_FLOAT_REGREG_REM_D)
202     (set DF rDD32F (rem DF rAD32F rBD32F))
203     ()
204     )
205
206(define-pmacro (get-rounding-mode)
207  (case INT sys-fpcsr-rm
208        ((0) 1) ; TIES-TO-EVEN -- I'm assuming this is what is meant by "round to nearest"
209        ((1) 3) ; TOWARD-ZERO
210        ((2) 4) ; TOWARD-POSITIVE
211        (else 5) ; TOWARD-NEGATIVE
212        )
213  )
214
215(dni lf-itof-s
216     "lf.itof.s reg/reg"
217     ((MACH ORFPX32-MACHS))
218     "lf.itof.s $rDSF,$rA"
219     (+ OPC_FLOAT rDSF rA (f-r3 0) (f-resv-10-3 0) OPC_FLOAT_REGREG_ITOF_S)
220     (set SF rDSF (float SF (get-rounding-mode) (trunc SI rA)))
221     ()
222     )
223
224(dni lf-itof-d
225     "lf.itof.d reg/reg"
226     ((MACH ORFPX64-MACHS))
227     "lf.itof.d $rDDF,$rA"
228     (+ OPC_FLOAT rDDF rA (f-r3 0) (f-resv-10-3 0) OPC_FLOAT_REGREG_ITOF_D)
229     (set DF rDDF (float DF (get-rounding-mode) rA))
230     ()
231     )
232
233(dni lf-itof-d32
234     "lf.itof.d regpair/regpair"
235     ((MACH ORFPX64A32-MACHS))
236     "lf.itof.d $rDD32F,$rADI"
237     (+ OPC_FLOAT rDD32F rADI (f-r3 0) (f-resv-8-1 0) OPC_FLOAT_REGREG_ITOF_D)
238     (set DF rDD32F (float DF (get-rounding-mode) rADI))
239     ()
240     )
241
242(dni lf-ftoi-s
243     "lf.ftoi.s reg/reg"
244     ((MACH ORFPX32-MACHS))
245     "lf.ftoi.s $rD,$rASF"
246     (+ OPC_FLOAT rD rASF (f-r3 0) (f-resv-10-3 0) OPC_FLOAT_REGREG_FTOI_S)
247     (set WI rD (ext WI (fix SI (get-rounding-mode) rASF)))
248     ()
249     )
250
251(dni lf-ftoi-d
252     "lf.ftoi.d reg/reg"
253     ((MACH ORFPX64-MACHS))
254     "lf.ftoi.d $rD,$rADF"
255     (+ OPC_FLOAT rD rADF (f-r3 0) (f-resv-10-3 0) OPC_FLOAT_REGREG_FTOI_D)
256     (set WI rD (fix WI (get-rounding-mode) rADF))
257     ()
258     )
259
260(dni lf-ftoi-d32
261     "lf.ftoi.d regpair/regpair"
262     ((MACH ORFPX64A32-MACHS))
263     "lf.ftoi.d $rDDI,$rAD32F"
264     (+ OPC_FLOAT rDDI rAD32F (f-r3 0) (f-resv-8-1 0) OPC_FLOAT_REGREG_FTOI_D)
265     (set DI rDDI (fix DI (get-rounding-mode) rAD32F))
266     ()
267     )
268
269(define-pmacro (float-setflag-insn-base mnemonic rtx-mnemonic symantics)
270  (begin
271    (dni (.sym lf-sf mnemonic -s)
272         (.str "lf.sf" mnemonic ".s reg/reg")
273         ((MACH ORFPX32-MACHS))
274         (.str "lf.sf" mnemonic ".s $rASF,$rBSF")
275         (+ OPC_FLOAT (f-r1 0) rASF rBSF (f-resv-10-3 0) (.sym OPC_FLOAT_REGREG_SF (.upcase mnemonic) _S))
276         (symantics rtx-mnemonic SF rASF rBSF)
277         ()
278         )
279    (dni (.sym lf-sf mnemonic -d)
280         (.str "lf.sf" mnemonic ".d reg/reg")
281         ((MACH ORFPX64-MACHS))
282         (.str "lf.sf" mnemonic ".d $rADF,$rBDF")
283         (+ OPC_FLOAT (f-r1 0) rADF rBDF (f-resv-10-3 0) (.sym OPC_FLOAT_REGREG_SF (.upcase mnemonic) _D))
284         (symantics rtx-mnemonic DF rADF rBDF)
285         ()
286         )
287    (dni (.sym lf-sf mnemonic -d32)
288         (.str "lf.sf" mnemonic ".d regpair/regpair")
289         ((MACH ORFPX64A32-MACHS))
290         (.str "lf.sf" mnemonic ".d $rAD32F,$rBD32F")
291         (+ OPC_FLOAT (f-r1 0) rAD32F rBD32F (f-resv-10-1 0) (.sym OPC_FLOAT_REGREG_SF (.upcase mnemonic) _D))
292         (symantics rtx-mnemonic DF rAD32F rBD32F)
293         ()
294         )
295    )
296  )
297
298(define-pmacro (float-setflag-symantics mnemonic mode r1 r2)
299  (set BI sys-sr-f (mnemonic mode r1 r2)))
300
301(define-pmacro (float-setflag-insn mnemonic)
302  (float-setflag-insn-base mnemonic mnemonic float-setflag-symantics))
303
304(define-pmacro (float-setflag-unordered-cmp-symantics mnemonic mode r1 r2)
305  (set BI sys-sr-f (or (unordered mode r1 r2)
306                       (mnemonic mode r1 r2))))
307
308(define-pmacro (float-setflag-unordered-symantics mnemonic mode r1 r2)
309  (set BI sys-sr-f (unordered mode r1 r2)))
310
311(define-pmacro (float-setflag-unordered-insn mnemonic)
312  (float-setflag-insn-base (.str "u" mnemonic)
313                           mnemonic
314                           float-setflag-unordered-cmp-symantics))
315
316(float-setflag-insn eq)
317(float-setflag-insn ne)
318(float-setflag-insn ge)
319(float-setflag-insn gt)
320(float-setflag-insn lt)
321(float-setflag-insn le)
322(float-setflag-unordered-insn eq)
323(float-setflag-unordered-insn ne)
324(float-setflag-unordered-insn gt)
325(float-setflag-unordered-insn ge)
326(float-setflag-unordered-insn lt)
327(float-setflag-unordered-insn le)
328(float-setflag-insn-base un () float-setflag-unordered-symantics)
329
330(dni lf-madd-s
331     "lf.madd.s reg/reg/reg"
332     ((MACH ORFPX32-MACHS))
333     "lf.madd.s $rDSF,$rASF,$rBSF"
334     (+ OPC_FLOAT rDSF rASF rBSF (f-resv-10-3 0) OPC_FLOAT_REGREG_MADD_S)
335     (set SF rDSF (add SF (mul SF rASF rBSF) rDSF))
336     ()
337     )
338
339(dni lf-madd-d
340     "lf.madd.d reg/reg/reg"
341     ((MACH ORFPX64-MACHS))
342     "lf.madd.d $rDDF,$rADF,$rBDF"
343     (+ OPC_FLOAT rDDF rADF rBDF (f-resv-10-3 0) OPC_FLOAT_REGREG_MADD_D)
344     (set DF rDDF (add DF (mul DF rADF rBDF) rDDF))
345     ()
346     )
347
348(dni lf-madd-d32
349     "lf.madd.d regpair/regpair/regpair"
350     ((MACH ORFPX64A32-MACHS))
351     "lf.madd.d $rDD32F,$rAD32F,$rBD32F"
352     (+ OPC_FLOAT rDD32F rAD32F rBD32F OPC_FLOAT_REGREG_MADD_D)
353     (set DF rDD32F (add DF (mul DF rAD32F rBD32F) rDD32F))
354     ()
355     )
356
357(define-pmacro (float-cust-insn cust-num)
358  (begin
359    (dni (.sym "lf-cust" cust-num "-s")
360         (.str "lf.cust" cust-num ".s")
361         ((MACH ORFPX32-MACHS))
362         (.str "lf.cust" cust-num ".s $rASF,$rBSF")
363         (+ OPC_FLOAT (f-resv-25-5 0) rASF rBSF (f-resv-10-3 0) (.sym "OPC_FLOAT_REGREG_CUST" cust-num "_S"))
364         (nop)
365         ()
366         )
367    (dni (.sym "lf-cust" cust-num "-d")
368         (.str "lf.cust" cust-num ".d")
369         ((MACH ORFPX64-MACHS))
370         (.str "lf.cust" cust-num ".d")
371         (+ OPC_FLOAT (f-resv-25-5 0) rADF rBDF (f-resv-10-3 0) (.sym "OPC_FLOAT_REGREG_CUST" cust-num "_D"))
372         (nop)
373         ()
374         )
375    (dni (.sym "lf-cust" cust-num "-d32")
376         (.str "lf.cust" cust-num ".d")
377         ((MACH ORFPX64A32-MACHS))
378         (.str "lf.cust" cust-num ".d")
379         (+ OPC_FLOAT (f-resv-25-5 0) rAD32F rBD32F (f-resv-10-1 0) (.sym "OPC_FLOAT_REGREG_CUST" cust-num "_D"))
380         (nop)
381         ()
382         )
383    )
384  )
385
386(float-cust-insn "1")
387