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