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(define-pmacro (double-field-and-ops mnemonic reg offbit op-comment) 88 (begin 89 (define-multi-ifield 90 (name (.sym "f-r" (.downcase mnemonic) "d32")) 91 (comment op-comment) 92 (attrs (MACH ORFPX64A32-MACHS)) 93 (mode SI) 94 (subfields reg offbit) 95 ; From the multi-ifield insert the bits into subfields 96 (insert (sequence 97 () 98 (set (ifield reg) 99 (and (ifield (.sym "f-r" (.downcase mnemonic) "d32")) 100 (const #x1f)) 101 ) 102 (set (ifield offbit) 103 (and (sra (ifield (.sym "f-r" (.downcase mnemonic) "d32")) 104 (const 5)) 105 (const 1)) 106 ) 107 ) 108 ) 109 ; Extract the multi-ifield from the subfield bits 110 (extract 111 (set (ifield (.sym "f-r" (.downcase mnemonic) "d32")) 112 (or (ifield reg) 113 (sll (ifield offbit) 114 (const 5))) 115 ) 116 ) 117 ) 118 (define-operand 119 (name (.sym "r" (.upcase mnemonic) "D32F")) 120 (comment (.str op-comment " (double floating point pair)")) 121 (attrs (MACH ORFPX64A32-MACHS)) 122 (type h-fd32r) 123 (index (.sym "f-r" (.downcase mnemonic) "d32")) 124 (handlers (parse "regpair") (print "regpair")) 125 ) 126 (define-operand 127 (name (.sym "r" (.upcase mnemonic) "DI")) 128 (comment (.str op-comment " (double integer pair)")) 129 (attrs (MACH ORFPX64A32-MACHS)) 130 (type h-i64r) 131 (index (.sym "f-r" (.downcase mnemonic) "d32")) 132 (handlers (parse "regpair") (print "regpair")) 133 ) 134 ) 135 ) 136 137(double-field-and-ops D f-r1 f-rdoff-10-1 "destination register") 138(double-field-and-ops A f-r2 f-raoff-9-1 "source register A") 139(double-field-and-ops B f-r3 f-rboff-8-1 "source register B") 140 141(define-pmacro (float-regreg-insn mnemonic) 142 (begin 143 (dni (.sym lf- mnemonic -s) 144 (.str "lf." mnemonic ".s reg/reg/reg") 145 ((MACH ORFPX32-MACHS)) 146 (.str "lf." mnemonic ".s $rDSF,$rASF,$rBSF") 147 (+ OPC_FLOAT rDSF rASF rBSF (f-resv-10-3 0) (.sym OPC_FLOAT_REGREG_ (.upcase mnemonic) _S)) 148 (set SF rDSF (mnemonic SF rASF rBSF)) 149 () 150 ) 151 (dni (.sym lf- mnemonic -d32) 152 (.str "lf." mnemonic ".d regpair/regpair/regpair") 153 ((MACH ORFPX64A32-MACHS)) 154 (.str "lf." mnemonic ".d $rDD32F,$rAD32F,$rBD32F") 155 (+ OPC_FLOAT rDD32F rAD32F rBD32F (.sym OPC_FLOAT_REGREG_ (.upcase mnemonic) _D)) 156 (set DF rDD32F (mnemonic DF rAD32F rBD32F)) 157 () 158 ) 159 ) 160 ) 161 162(float-regreg-insn add) 163(float-regreg-insn sub) 164(float-regreg-insn mul) 165(float-regreg-insn div) 166 167(dni lf-rem-s 168 "lf.rem.s reg/reg/reg" 169 ((MACH ORFPX32-MACHS)) 170 "lf.rem.s $rDSF,$rASF,$rBSF" 171 (+ OPC_FLOAT rDSF rASF rBSF (f-resv-10-3 0) OPC_FLOAT_REGREG_REM_S) 172 (set SF rDSF (rem SF rASF rBSF)) 173 () 174 ) 175 176(dni lf-rem-d32 177 "lf.rem.d regpair/regpair/regpair" 178 ((MACH ORFPX64A32-MACHS)) 179 "lf.rem.d $rDD32F,$rAD32F,$rBD32F" 180 (+ OPC_FLOAT rDD32F rAD32F rBD32F OPC_FLOAT_REGREG_REM_D) 181 (set DF rDD32F (rem DF rAD32F rBD32F)) 182 () 183 ) 184 185(define-pmacro (get-rounding-mode) 186 (case INT sys-fpcsr-rm 187 ((0) 1) ; TIES-TO-EVEN -- I'm assuming this is what is meant by "round to nearest" 188 ((1) 3) ; TOWARD-ZERO 189 ((2) 4) ; TOWARD-POSITIVE 190 (else 5) ; TOWARD-NEGATIVE 191 ) 192 ) 193 194(dni lf-itof-s 195 "lf.itof.s reg/reg" 196 ((MACH ORFPX32-MACHS)) 197 "lf.itof.s $rDSF,$rA" 198 (+ OPC_FLOAT rDSF rA (f-r3 0) (f-resv-10-3 0) OPC_FLOAT_REGREG_ITOF_S) 199 (set SF rDSF (float SF (get-rounding-mode) (trunc SI rA))) 200 () 201 ) 202 203(dni lf-itof-d32 204 "lf.itof.d regpair/regpair" 205 ((MACH ORFPX64A32-MACHS)) 206 "lf.itof.d $rDD32F,$rADI" 207 (+ OPC_FLOAT rDD32F rADI (f-r3 0) (f-resv-8-1 0) OPC_FLOAT_REGREG_ITOF_D) 208 (set DF rDD32F (float DF (get-rounding-mode) rADI)) 209 () 210 ) 211 212(dni lf-ftoi-s 213 "lf.ftoi.s reg/reg" 214 ((MACH ORFPX32-MACHS)) 215 "lf.ftoi.s $rD,$rASF" 216 (+ OPC_FLOAT rD rASF (f-r3 0) (f-resv-10-3 0) OPC_FLOAT_REGREG_FTOI_S) 217 (set WI rD (ext WI (fix SI (get-rounding-mode) rASF))) 218 () 219 ) 220 221(dni lf-ftoi-d32 222 "lf.ftoi.d regpair/regpair" 223 ((MACH ORFPX64A32-MACHS)) 224 "lf.ftoi.d $rDDI,$rAD32F" 225 (+ OPC_FLOAT rDDI rAD32F (f-r3 0) (f-resv-8-1 0) OPC_FLOAT_REGREG_FTOI_D) 226 (set DI rDDI (fix DI (get-rounding-mode) rAD32F)) 227 () 228 ) 229 230(define-pmacro (float-setflag-insn-base mnemonic rtx-mnemonic symantics) 231 (begin 232 (dni (.sym lf-sf mnemonic -s) 233 (.str "lf.sf" mnemonic ".s reg/reg") 234 ((MACH ORFPX32-MACHS)) 235 (.str "lf.sf" mnemonic ".s $rASF,$rBSF") 236 (+ OPC_FLOAT (f-r1 0) rASF rBSF (f-resv-10-3 0) (.sym OPC_FLOAT_REGREG_SF (.upcase mnemonic) _S)) 237 (symantics rtx-mnemonic SF rASF rBSF) 238 () 239 ) 240 (dni (.sym lf-sf mnemonic -d32) 241 (.str "lf.sf" mnemonic ".d regpair/regpair") 242 ((MACH ORFPX64A32-MACHS)) 243 (.str "lf.sf" mnemonic ".d $rAD32F,$rBD32F") 244 (+ OPC_FLOAT (f-r1 0) rAD32F rBD32F (f-resv-10-1 0) (.sym OPC_FLOAT_REGREG_SF (.upcase mnemonic) _D)) 245 (symantics rtx-mnemonic DF rAD32F rBD32F) 246 () 247 ) 248 ) 249 ) 250 251(define-pmacro (float-setflag-symantics mnemonic mode r1 r2) 252 (set BI sys-sr-f (mnemonic mode r1 r2))) 253 254(define-pmacro (float-setflag-insn mnemonic) 255 (float-setflag-insn-base mnemonic mnemonic float-setflag-symantics)) 256 257(define-pmacro (float-setflag-unordered-cmp-symantics mnemonic mode r1 r2) 258 (set BI sys-sr-f (or (unordered mode r1 r2) 259 (mnemonic mode r1 r2)))) 260 261(define-pmacro (float-setflag-unordered-symantics mnemonic mode r1 r2) 262 (set BI sys-sr-f (unordered mode r1 r2))) 263 264(define-pmacro (float-setflag-unordered-insn mnemonic) 265 (float-setflag-insn-base (.str "u" mnemonic) 266 mnemonic 267 float-setflag-unordered-cmp-symantics)) 268 269(float-setflag-insn eq) 270(float-setflag-insn ne) 271(float-setflag-insn ge) 272(float-setflag-insn gt) 273(float-setflag-insn lt) 274(float-setflag-insn le) 275(float-setflag-unordered-insn eq) 276(float-setflag-unordered-insn ne) 277(float-setflag-unordered-insn gt) 278(float-setflag-unordered-insn ge) 279(float-setflag-unordered-insn lt) 280(float-setflag-unordered-insn le) 281(float-setflag-insn-base un () float-setflag-unordered-symantics) 282 283(dni lf-madd-s 284 "lf.madd.s reg/reg/reg" 285 ((MACH ORFPX32-MACHS)) 286 "lf.madd.s $rDSF,$rASF,$rBSF" 287 (+ OPC_FLOAT rDSF rASF rBSF (f-resv-10-3 0) OPC_FLOAT_REGREG_MADD_S) 288 (set SF rDSF (add SF (mul SF rASF rBSF) rDSF)) 289 () 290 ) 291 292(dni lf-madd-d32 293 "lf.madd.d regpair/regpair/regpair" 294 ((MACH ORFPX64A32-MACHS)) 295 "lf.madd.d $rDD32F,$rAD32F,$rBD32F" 296 (+ OPC_FLOAT rDD32F rAD32F rBD32F OPC_FLOAT_REGREG_MADD_D) 297 (set DF rDD32F (add DF (mul DF rAD32F rBD32F) rDD32F)) 298 () 299 ) 300 301(define-pmacro (float-cust-insn cust-num) 302 (begin 303 (dni (.sym "lf-cust" cust-num "-s") 304 (.str "lf.cust" cust-num ".s") 305 ((MACH ORFPX32-MACHS)) 306 (.str "lf.cust" cust-num ".s $rASF,$rBSF") 307 (+ OPC_FLOAT (f-resv-25-5 0) rASF rBSF (f-resv-10-3 0) (.sym "OPC_FLOAT_REGREG_CUST" cust-num "_S")) 308 (nop) 309 () 310 ) 311 (dni (.sym "lf-cust" cust-num "-d32") 312 (.str "lf.cust" cust-num ".d") 313 ((MACH ORFPX64A32-MACHS)) 314 (.str "lf.cust" cust-num ".d") 315 (+ OPC_FLOAT (f-resv-25-5 0) rAD32F rBD32F (f-resv-10-1 0) (.sym "OPC_FLOAT_REGREG_CUST" cust-num "_D")) 316 (nop) 317 () 318 ) 319 ) 320 ) 321 322(float-cust-insn "1") 323