cpu/or1k: Document no branch delay slot architectures and l.adrp
[external/binutils.git] / cpu / or1korfpx.cpu
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- 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- 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- 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")