| 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") |