| ; OpenRISC 1000 architecture. -*- Scheme -*- |
| ; Copyright 2000-2019 Free Software Foundation, Inc. |
| ; Contributed by Peter Gavin, pgavin@gmail.com |
| ; Modified by Andrey Bacherov, avbacherov@opencores.org |
| ; |
| ; This program is free software; you can redistribute it and/or modify |
| ; it under the terms of the GNU General Public License as published by |
| ; the Free Software Foundation; either version 3 of the License, or |
| ; (at your option) any later version. |
| ; |
| ; This program is distributed in the hope that it will be useful, |
| ; but WITHOUT ANY WARRANTY; without even the implied warranty of |
| ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| ; GNU General Public License for more details. |
| ; |
| ; You should have received a copy of the GNU General Public License |
| ; along with this program; if not, see <http://www.gnu.org/licenses/> |
| |
| ; Initial ORFPX32 instruction set |
| |
| ; I'm not sure how CGEN handles rounding in FP operations, except for |
| ; in conversions to/from integers. So lf.add, lf.sub, lf.mul, and |
| ; lf.div do not round according to the FPCSR RM field. |
| ; NaN, overflow, and underflow are not yet handled either. |
| |
| (define-normal-insn-enum insn-opcode-float-regreg |
| "floating point reg/reg insn opcode enums" () |
| OPC_FLOAT_REGREG_ f-op-7-8 |
| (("ADD_S" #x00) |
| ("SUB_S" #x01) |
| ("MUL_S" #x02) |
| ("DIV_S" #x03) |
| ("ITOF_S" #x04) |
| ("FTOI_S" #x05) |
| ("REM_S" #x06) |
| ("MADD_S" #x07) |
| ("SFEQ_S" #x08) |
| ("SFNE_S" #x09) |
| ("SFGT_S" #x0a) |
| ("SFGE_S" #x0b) |
| ("SFLT_S" #x0c) |
| ("SFLE_S" #x0d) |
| ("ADD_D" #x10) |
| ("SUB_D" #x11) |
| ("MUL_D" #x12) |
| ("DIV_D" #x13) |
| ("ITOF_D" #x14) |
| ("FTOI_D" #x15) |
| ("REM_D" #x16) |
| ("MADD_D" #x17) |
| ("SFEQ_D" #x18) |
| ("SFNE_D" #x19) |
| ("SFGT_D" #x1a) |
| ("SFGE_D" #x1b) |
| ("SFLT_D" #x1c) |
| ("SFLE_D" #x1d) |
| ("SFUEQ_S" #x28) |
| ("SFUNE_S" #x29) |
| ("SFUGT_S" #x2a) |
| ("SFUGE_S" #x2b) |
| ("SFULT_S" #x2c) |
| ("SFULE_S" #x2d) |
| ("SFUN_S" #x2e) |
| ("SFUEQ_D" #x38) |
| ("SFUNE_D" #x39) |
| ("SFUGT_D" #x3a) |
| ("SFUGE_D" #x3b) |
| ("SFULT_D" #x3c) |
| ("SFULE_D" #x3d) |
| ("SFUN_D" #x3e) |
| ("CUST1_S" #xd0) |
| ("CUST1_D" #xe0) |
| ) |
| ) |
| |
| ; Register offset flags, if set offset is 2 otherwise offset is 1 |
| (dnf f-rdoff-10-1 "destination register pair offset flag" ((MACH ORFPX64A32-MACHS)) 10 1) |
| (dnf f-raoff-9-1 "source register A pair offset flag" ((MACH ORFPX64A32-MACHS)) 9 1) |
| (dnf f-rboff-8-1 "source register B pair offset flag" ((MACH ORFPX64A32-MACHS)) 8 1) |
| |
| (dsh h-roff1 "1-bit offset flag" () (register BI)) |
| |
| (dnop rDSF "destination register (single floating point mode)" ((MACH ORFPX32-MACHS)) h-fsr f-r1) |
| (dnop rASF "source register A (single floating point mode)" ((MACH ORFPX32-MACHS)) h-fsr f-r2) |
| (dnop rBSF "source register B (single floating point mode)" ((MACH ORFPX32-MACHS)) h-fsr f-r3) |
| |
| (define-pmacro (double-field-and-ops mnemonic reg offbit op-comment) |
| (begin |
| (define-multi-ifield |
| (name (.sym "f-r" (.downcase mnemonic) "d32")) |
| (comment op-comment) |
| (attrs (MACH ORFPX64A32-MACHS)) |
| (mode SI) |
| (subfields reg offbit) |
| ; From the multi-ifield insert the bits into subfields |
| (insert (sequence |
| () |
| (set (ifield reg) |
| (and (ifield (.sym "f-r" (.downcase mnemonic) "d32")) |
| (const #x1f)) |
| ) |
| (set (ifield offbit) |
| (and (sra (ifield (.sym "f-r" (.downcase mnemonic) "d32")) |
| (const 5)) |
| (const 1)) |
| ) |
| ) |
| ) |
| ; Extract the multi-ifield from the subfield bits |
| (extract |
| (set (ifield (.sym "f-r" (.downcase mnemonic) "d32")) |
| (or (ifield reg) |
| (sll (ifield offbit) |
| (const 5))) |
| ) |
| ) |
| ) |
| (define-operand |
| (name (.sym "r" (.upcase mnemonic) "D32F")) |
| (comment (.str op-comment " (double floating point pair)")) |
| (attrs (MACH ORFPX64A32-MACHS)) |
| (type h-fd32r) |
| (index (.sym "f-r" (.downcase mnemonic) "d32")) |
| (handlers (parse "regpair") (print "regpair")) |
| ) |
| (define-operand |
| (name (.sym "r" (.upcase mnemonic) "DI")) |
| (comment (.str op-comment " (double integer pair)")) |
| (attrs (MACH ORFPX64A32-MACHS)) |
| (type h-i64r) |
| (index (.sym "f-r" (.downcase mnemonic) "d32")) |
| (handlers (parse "regpair") (print "regpair")) |
| ) |
| ) |
| ) |
| |
| (double-field-and-ops D f-r1 f-rdoff-10-1 "destination register") |
| (double-field-and-ops A f-r2 f-raoff-9-1 "source register A") |
| (double-field-and-ops B f-r3 f-rboff-8-1 "source register B") |
| |
| (define-pmacro (float-regreg-insn mnemonic) |
| (begin |
| (dni (.sym lf- mnemonic -s) |
| (.str "lf." mnemonic ".s reg/reg/reg") |
| ((MACH ORFPX32-MACHS)) |
| (.str "lf." mnemonic ".s $rDSF,$rASF,$rBSF") |
| (+ OPC_FLOAT rDSF rASF rBSF (f-resv-10-3 0) (.sym OPC_FLOAT_REGREG_ (.upcase mnemonic) _S)) |
| (set SF rDSF (mnemonic SF rASF rBSF)) |
| () |
| ) |
| (dni (.sym lf- mnemonic -d32) |
| (.str "lf." mnemonic ".d regpair/regpair/regpair") |
| ((MACH ORFPX64A32-MACHS)) |
| (.str "lf." mnemonic ".d $rDD32F,$rAD32F,$rBD32F") |
| (+ OPC_FLOAT rDD32F rAD32F rBD32F (.sym OPC_FLOAT_REGREG_ (.upcase mnemonic) _D)) |
| (set DF rDD32F (mnemonic DF rAD32F rBD32F)) |
| () |
| ) |
| ) |
| ) |
| |
| (float-regreg-insn add) |
| (float-regreg-insn sub) |
| (float-regreg-insn mul) |
| (float-regreg-insn div) |
| |
| (dni lf-rem-s |
| "lf.rem.s reg/reg/reg" |
| ((MACH ORFPX32-MACHS)) |
| "lf.rem.s $rDSF,$rASF,$rBSF" |
| (+ OPC_FLOAT rDSF rASF rBSF (f-resv-10-3 0) OPC_FLOAT_REGREG_REM_S) |
| (set SF rDSF (rem SF rASF rBSF)) |
| () |
| ) |
| |
| (dni lf-rem-d32 |
| "lf.rem.d regpair/regpair/regpair" |
| ((MACH ORFPX64A32-MACHS)) |
| "lf.rem.d $rDD32F,$rAD32F,$rBD32F" |
| (+ OPC_FLOAT rDD32F rAD32F rBD32F OPC_FLOAT_REGREG_REM_D) |
| (set DF rDD32F (rem DF rAD32F rBD32F)) |
| () |
| ) |
| |
| (define-pmacro (get-rounding-mode) |
| (case INT sys-fpcsr-rm |
| ((0) 1) ; TIES-TO-EVEN -- I'm assuming this is what is meant by "round to nearest" |
| ((1) 3) ; TOWARD-ZERO |
| ((2) 4) ; TOWARD-POSITIVE |
| (else 5) ; TOWARD-NEGATIVE |
| ) |
| ) |
| |
| (dni lf-itof-s |
| "lf.itof.s reg/reg" |
| ((MACH ORFPX32-MACHS)) |
| "lf.itof.s $rDSF,$rA" |
| (+ OPC_FLOAT rDSF rA (f-r3 0) (f-resv-10-3 0) OPC_FLOAT_REGREG_ITOF_S) |
| (set SF rDSF (float SF (get-rounding-mode) (trunc SI rA))) |
| () |
| ) |
| |
| (dni lf-itof-d32 |
| "lf.itof.d regpair/regpair" |
| ((MACH ORFPX64A32-MACHS)) |
| "lf.itof.d $rDD32F,$rADI" |
| (+ OPC_FLOAT rDD32F rADI (f-r3 0) (f-resv-8-1 0) OPC_FLOAT_REGREG_ITOF_D) |
| (set DF rDD32F (float DF (get-rounding-mode) rADI)) |
| () |
| ) |
| |
| (dni lf-ftoi-s |
| "lf.ftoi.s reg/reg" |
| ((MACH ORFPX32-MACHS)) |
| "lf.ftoi.s $rD,$rASF" |
| (+ OPC_FLOAT rD rASF (f-r3 0) (f-resv-10-3 0) OPC_FLOAT_REGREG_FTOI_S) |
| (set WI rD (ext WI (fix SI (get-rounding-mode) rASF))) |
| () |
| ) |
| |
| (dni lf-ftoi-d32 |
| "lf.ftoi.d regpair/regpair" |
| ((MACH ORFPX64A32-MACHS)) |
| "lf.ftoi.d $rDDI,$rAD32F" |
| (+ OPC_FLOAT rDDI rAD32F (f-r3 0) (f-resv-8-1 0) OPC_FLOAT_REGREG_FTOI_D) |
| (set DI rDDI (fix DI (get-rounding-mode) rAD32F)) |
| () |
| ) |
| |
| (define-pmacro (float-setflag-insn-base mnemonic rtx-mnemonic symantics) |
| (begin |
| (dni (.sym lf-sf mnemonic -s) |
| (.str "lf.sf" mnemonic ".s reg/reg") |
| ((MACH ORFPX32-MACHS)) |
| (.str "lf.sf" mnemonic ".s $rASF,$rBSF") |
| (+ OPC_FLOAT (f-r1 0) rASF rBSF (f-resv-10-3 0) (.sym OPC_FLOAT_REGREG_SF (.upcase mnemonic) _S)) |
| (symantics rtx-mnemonic SF rASF rBSF) |
| () |
| ) |
| (dni (.sym lf-sf mnemonic -d32) |
| (.str "lf.sf" mnemonic ".d regpair/regpair") |
| ((MACH ORFPX64A32-MACHS)) |
| (.str "lf.sf" mnemonic ".d $rAD32F,$rBD32F") |
| (+ OPC_FLOAT (f-r1 0) rAD32F rBD32F (f-resv-10-1 0) (.sym OPC_FLOAT_REGREG_SF (.upcase mnemonic) _D)) |
| (symantics rtx-mnemonic DF rAD32F rBD32F) |
| () |
| ) |
| ) |
| ) |
| |
| (define-pmacro (float-setflag-symantics mnemonic mode r1 r2) |
| (set BI sys-sr-f (mnemonic mode r1 r2))) |
| |
| (define-pmacro (float-setflag-insn mnemonic) |
| (float-setflag-insn-base mnemonic mnemonic float-setflag-symantics)) |
| |
| (define-pmacro (float-setflag-unordered-cmp-symantics mnemonic mode r1 r2) |
| (set BI sys-sr-f (or (unordered mode r1 r2) |
| (mnemonic mode r1 r2)))) |
| |
| (define-pmacro (float-setflag-unordered-symantics mnemonic mode r1 r2) |
| (set BI sys-sr-f (unordered mode r1 r2))) |
| |
| (define-pmacro (float-setflag-unordered-insn mnemonic) |
| (float-setflag-insn-base (.str "u" mnemonic) |
| mnemonic |
| float-setflag-unordered-cmp-symantics)) |
| |
| (float-setflag-insn eq) |
| (float-setflag-insn ne) |
| (float-setflag-insn ge) |
| (float-setflag-insn gt) |
| (float-setflag-insn lt) |
| (float-setflag-insn le) |
| (float-setflag-unordered-insn eq) |
| (float-setflag-unordered-insn ne) |
| (float-setflag-unordered-insn gt) |
| (float-setflag-unordered-insn ge) |
| (float-setflag-unordered-insn lt) |
| (float-setflag-unordered-insn le) |
| (float-setflag-insn-base un () float-setflag-unordered-symantics) |
| |
| (dni lf-madd-s |
| "lf.madd.s reg/reg/reg" |
| ((MACH ORFPX32-MACHS)) |
| "lf.madd.s $rDSF,$rASF,$rBSF" |
| (+ OPC_FLOAT rDSF rASF rBSF (f-resv-10-3 0) OPC_FLOAT_REGREG_MADD_S) |
| (set SF rDSF (add SF (mul SF rASF rBSF) rDSF)) |
| () |
| ) |
| |
| (dni lf-madd-d32 |
| "lf.madd.d regpair/regpair/regpair" |
| ((MACH ORFPX64A32-MACHS)) |
| "lf.madd.d $rDD32F,$rAD32F,$rBD32F" |
| (+ OPC_FLOAT rDD32F rAD32F rBD32F OPC_FLOAT_REGREG_MADD_D) |
| (set DF rDD32F (add DF (mul DF rAD32F rBD32F) rDD32F)) |
| () |
| ) |
| |
| (define-pmacro (float-cust-insn cust-num) |
| (begin |
| (dni (.sym "lf-cust" cust-num "-s") |
| (.str "lf.cust" cust-num ".s") |
| ((MACH ORFPX32-MACHS)) |
| (.str "lf.cust" cust-num ".s $rASF,$rBSF") |
| (+ OPC_FLOAT (f-resv-25-5 0) rASF rBSF (f-resv-10-3 0) (.sym "OPC_FLOAT_REGREG_CUST" cust-num "_S")) |
| (nop) |
| () |
| ) |
| (dni (.sym "lf-cust" cust-num "-d32") |
| (.str "lf.cust" cust-num ".d") |
| ((MACH ORFPX64A32-MACHS)) |
| (.str "lf.cust" cust-num ".d") |
| (+ OPC_FLOAT (f-resv-25-5 0) rAD32F rBD32F (f-resv-10-1 0) (.sym "OPC_FLOAT_REGREG_CUST" cust-num "_D")) |
| (nop) |
| () |
| ) |
| ) |
| ) |
| |
| (float-cust-insn "1") |