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
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.
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.
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/>
19 ; Initial ORFPX32 instruction set
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.
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
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)
81 (dsh h-roff1 "1-bit offset flag" () (register BI))
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)
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)
91 (define-pmacro (double-field-and-ops mnemonic reg offbit op-comment)
94 (name (.sym "f-r" (.downcase mnemonic) "d32"))
96 (attrs (MACH ORFPX64A32-MACHS))
98 (subfields reg offbit)
99 ; From the multi-ifield insert the bits into subfields
103 (and (ifield (.sym "f-r" (.downcase mnemonic) "d32"))
107 (and (sra (ifield (.sym "f-r" (.downcase mnemonic) "d32"))
113 ; Extract the multi-ifield from the subfield bits
115 (set (ifield (.sym "f-r" (.downcase mnemonic) "d32"))
123 (name (.sym "r" (.upcase mnemonic) "D32F"))
124 (comment (.str op-comment " (double floating point pair)"))
125 (attrs (MACH ORFPX64A32-MACHS))
127 (index (.sym "f-r" (.downcase mnemonic) "d32"))
128 (handlers (parse "regpair") (print "regpair"))
131 (name (.sym "r" (.upcase mnemonic) "DI"))
132 (comment (.str op-comment " (double integer pair)"))
133 (attrs (MACH ORFPX64A32-MACHS))
135 (index (.sym "f-r" (.downcase mnemonic) "d32"))
136 (handlers (parse "regpair") (print "regpair"))
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")
145 (define-pmacro (float-regreg-insn mnemonic)
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))
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))
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))
174 (float-regreg-insn add)
175 (float-regreg-insn sub)
176 (float-regreg-insn mul)
177 (float-regreg-insn div)
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))
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))
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))
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
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)))
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))
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))
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)))
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))
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))
269 (define-pmacro (float-setflag-insn-base mnemonic rtx-mnemonic symantics)
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)
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)
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)
298 (define-pmacro (float-setflag-symantics mnemonic mode r1 r2)
299 (set BI sys-sr-f (mnemonic mode r1 r2)))
301 (define-pmacro (float-setflag-insn mnemonic)
302 (float-setflag-insn-base mnemonic mnemonic float-setflag-symantics))
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))))
308 (define-pmacro (float-setflag-unordered-symantics mnemonic mode r1 r2)
309 (set BI sys-sr-f (unordered mode r1 r2)))
311 (define-pmacro (float-setflag-unordered-insn mnemonic)
312 (float-setflag-insn-base (.str "u" mnemonic)
314 float-setflag-unordered-cmp-symantics))
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)
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))
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))
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))
357 (define-pmacro (float-cust-insn cust-num)
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"))
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"))
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"))
386 (float-cust-insn "1")