1; OpenRISC 1000 architecture.  -*- Scheme -*-
2; Copyright 2000-2014 Free Software Foundation, Inc.
3; Contributed by Peter Gavin, pgavin@gmail.com
4;
5; This program is free software; you can redistribute it and/or modify
6; it under the terms of the GNU General Public License as published by
7; the Free Software Foundation; either version 3 of the License, or
8; (at your option) any later version.
9;
10; This program is distributed in the hope that it will be useful,
11; but WITHOUT ANY WARRANTY; without even the implied warranty of
12; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13; GNU General Public License for more details.
14;
15; You should have received a copy of the GNU General Public License
16; along with this program; if not, see <http://www.gnu.org/licenses/>
17
18; Initial ORFPX32 instruction set
19
20; I'm not sure how CGEN handles rounding in FP operations, except for
21; in conversions to/from integers.  So lf.add, lf.sub, lf.mul, and
22; lf.div do not round according to the FPCSR RM field.
23; NaN, overflow, and underflow are not yet handled either.
24
25(define-normal-insn-enum insn-opcode-float-regreg
26  "floating point reg/reg insn opcode enums" ()
27  OPC_FLOAT_REGREG_ f-op-7-8
28  (("ADD_S"  #x00)
29   ("SUB_S"  #x01)
30   ("MUL_S"  #x02)
31   ("DIV_S"  #x03)
32   ("ITOF_S" #x04)
33   ("FTOI_S" #x05)
34   ("REM_S"  #x06)
35   ("MADD_S" #x07)
36   ("SFEQ_S" #x08)
37   ("SFNE_S" #x09)
38   ("SFGT_S" #x0a)
39   ("SFGE_S" #x0b)
40   ("SFLT_S" #x0c)
41   ("SFLE_S" #x0d)
42   ("ADD_D"  #x10)
43   ("SUB_D"  #x11)
44   ("MUL_D"  #x12)
45   ("DIV_D"  #x13)
46   ("ITOF_D" #x14)
47   ("FTOI_D" #x15)
48   ("REM_D"  #x16)
49   ("MADD_D" #x17)
50   ("SFEQ_D" #x18)
51   ("SFNE_D" #x19)
52   ("SFGT_D" #x1a)
53   ("SFGE_D" #x1b)
54   ("SFLT_D" #x1c)
55   ("SFLE_D" #x1d)
56   ("CUST1_S" #xd0)
57   ("CUST1_D" #xe0)
58   )
59  )
60
61(dnop rDSF "destination register (single floating point mode)" () h-fsr f-r1)
62(dnop rASF "source register A (single floating point mode)"    () h-fsr f-r2)
63(dnop rBSF "source register B (single floating point mode)"    () h-fsr f-r3)
64
65(dnop rDDF "destination register (double floating point mode)" ((MACH ORFPX64-MACHS)) h-fdr f-r1)
66(dnop rADF "source register A (double floating point mode)"    ((MACH ORFPX64-MACHS)) h-fdr f-r1)
67(dnop rBDF "source register B (double floating point mode)"    ((MACH ORFPX64-MACHS)) h-fdr f-r1)
68
69(define-pmacro (float-regreg-insn mnemonic)
70  (begin
71    (dni (.sym lf- mnemonic -s)
72         (.str "lf." mnemonic ".s reg/reg/reg")
73         ((MACH ORFPX-MACHS))
74         (.str "lf." mnemonic ".s $rDSF,$rASF,$rBSF")
75         (+ OPC_FLOAT rDSF rASF rBSF (f-resv-10-3 0) (.sym OPC_FLOAT_REGREG_ (.upcase mnemonic) _S))
76         (set SF rDSF (mnemonic SF rASF rBSF))
77         ()
78         )
79    (dni (.sym lf- mnemonic -d)
80         (.str "lf." mnemonic ".d reg/reg/reg")
81         ((MACH ORFPX64-MACHS))
82         (.str "lf." mnemonic ".d $rDDF,$rADF,$rBDF")
83         (+ OPC_FLOAT rDDF rADF rBDF (f-resv-10-3 0) (.sym OPC_FLOAT_REGREG_ (.upcase mnemonic) _D))
84         (set DF rDDF (mnemonic DF rADF rBDF))
85         ()
86         )
87    )
88  )
89
90(float-regreg-insn add)
91(float-regreg-insn sub)
92(float-regreg-insn mul)
93(float-regreg-insn div)
94
95(dni lf-rem-s
96     "lf.rem.s reg/reg/reg"
97     ((MACH ORFPX-MACHS))
98     "lf.rem.s $rDSF,$rASF,$rBSF"
99     (+ OPC_FLOAT rDSF rASF rBSF (f-resv-10-3 0) OPC_FLOAT_REGREG_REM_S)
100     (set SF rDSF (rem SF rASF rBSF))
101     ()
102     )
103(dni lf-rem-d
104     "lf.rem.d reg/reg/reg"
105     ((MACH ORFPX64-MACHS))
106     "lf.rem.d $rDDF,$rADF,$rBDF"
107     (+ OPC_FLOAT rDDF rADF rBDF (f-resv-10-3 0) OPC_FLOAT_REGREG_REM_D)
108     (set DF rDDF (mod DF rADF rBDF))
109     ()
110     )
111
112(define-pmacro (get-rounding-mode)
113  (case INT sys-fpcsr-rm
114        ((0) 1) ; TIES-TO-EVEN -- I'm assuming this is what is meant by "round to nearest"
115        ((1) 3) ; TOWARD-ZERO
116        ((2) 4) ; TOWARD-POSITIVE
117        (else 5) ; TOWARD-NEGATIVE
118        )
119  )
120
121(dni lf-itof-s
122     "lf.itof.s reg/reg"
123     ((MACH ORFPX-MACHS))
124     "lf.itof.s $rDSF,$rA"
125     (+ OPC_FLOAT rDSF rA (f-r3 0) (f-resv-10-3 0) OPC_FLOAT_REGREG_ITOF_S)
126     (set SF rDSF (float SF (get-rounding-mode) (trunc SI rA)))
127     ()
128     )
129(dni lf-itof-d
130     "lf.itof.d reg/reg"
131     ((MACH ORFPX64-MACHS))
132     "lf.itof.d $rDSF,$rA"
133     (+ OPC_FLOAT rDSF rA (f-r3 0) (f-resv-10-3 0) OPC_FLOAT_REGREG_ITOF_D)
134     (set DF rDDF (float DF (get-rounding-mode) rA))
135     ()
136     )
137
138(dni lf-ftoi-s
139     "lf.ftoi.s reg/reg"
140     ((MACH ORFPX-MACHS))
141     "lf.ftoi.s $rD,$rASF"
142     (+ OPC_FLOAT rD rASF (f-r3 0) (f-resv-10-3 0) OPC_FLOAT_REGREG_FTOI_S)
143     (set WI rD (ext WI (fix SI (get-rounding-mode) rASF)))
144     ()
145     )
146
147(dni lf-ftoi-d
148     "lf.ftoi.d reg/reg"
149     ((MACH ORFPX64-MACHS))
150     "lf.ftoi.d $rD,$rADF"
151     (+ OPC_FLOAT rD rADF (f-r3 0) (f-resv-10-3 0) OPC_FLOAT_REGREG_FTOI_D)
152     (set DI rD (fix DI (get-rounding-mode) rADF))
153     ()
154     )
155
156(define-pmacro (float-setflag-insn mnemonic)
157  (begin
158    (dni (.sym lf- mnemonic -s)
159         (.str "lf.sf" mnemonic ".s reg/reg")
160         ((MACH ORFPX-MACHS))
161         (.str "lf.sf" mnemonic ".s $rASF,$rBSF")
162         (+ OPC_FLOAT (f-r1 0) rASF rBSF (f-resv-10-3 0) (.sym OPC_FLOAT_REGREG_SF (.upcase mnemonic) _S))
163         (set BI sys-sr-f (mnemonic SF rASF rBSF))
164         ()
165         )
166    (dni (.sym lf- mnemonic -d)
167         (.str "lf.sf" mnemonic ".d reg/reg")
168         ((MACH ORFPX64-MACHS))
169         (.str "lf.sf" mnemonic ".d $rASF,$rBSF")
170         (+ OPC_FLOAT (f-r1 0) rASF rBSF (f-resv-10-3 0) (.sym OPC_FLOAT_REGREG_SF (.upcase mnemonic) _D))
171         (set BI sys-sr-f (mnemonic DF rADF rBDF))
172         ()
173         )
174    )
175  )
176
177(float-setflag-insn eq)
178(float-setflag-insn ne)
179(float-setflag-insn ge)
180(float-setflag-insn gt)
181(float-setflag-insn lt)
182(float-setflag-insn le)
183
184(dni lf-madd-s
185     "lf.madd.s reg/reg/reg"
186     ((MACH ORFPX-MACHS))
187     "lf.madd.s $rDSF,$rASF,$rBSF"
188     (+ OPC_FLOAT rDSF rASF rBSF (f-resv-10-3 0) OPC_FLOAT_REGREG_MADD_S)
189     (set SF rDSF (add SF (mul SF rASF rBSF) rDSF))
190     ()
191     )
192(dni lf-madd-d
193     "lf.madd.d reg/reg/reg"
194     ((MACH ORFPX64-MACHS))
195     "lf.madd.d $rDDF,$rADF,$rBDF"
196     (+ OPC_FLOAT rDDF rADF rBDF (f-resv-10-3 0) OPC_FLOAT_REGREG_MADD_D)
197     (set DF rDDF (add DF (mul DF rADF rBDF) rDDF))
198     ()
199     )
200
201(define-pmacro (float-cust-insn cust-num)
202  (begin
203    (dni (.sym "lf-cust" cust-num "-s")
204         (.str "lf.cust" cust-num ".s")
205         ((MACH ORFPX-MACHS))
206         (.str "lf.cust" cust-num ".s $rASF,$rBSF")
207         (+ OPC_FLOAT (f-resv-25-5 0) rASF rBSF (f-resv-10-3 0) (.sym "OPC_FLOAT_REGREG_CUST" cust-num "_S"))
208         (nop)
209         ()
210         )
211    (dni (.sym "lf-cust" cust-num "-d")
212         (.str "lf.cust" cust-num ".d")
213         ((MACH ORFPX64-MACHS))
214         (.str "lf.cust" cust-num ".d")
215         (+ OPC_FLOAT (f-resv-25-5 0) rADF rBDF (f-resv-10-3 0) (.sym "OPC_FLOAT_REGREG_CUST" cust-num "_D"))
216         (nop)
217         ()
218         )
219    )
220  )
221
222(float-cust-insn "1")
223