Commit | Line | Data |
---|---|---|
73589c9d CS |
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") |