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