d3ad6278d6
Add support for new floating point unordered comparisons. These have been defined in OpenRISC architecture proposal 7[0] and are now included in the architecture specification 1.3. These new instructions provide the ability for floating point comparisons to detect NaNs. [0] https://openrisc.io/proposals/lfsf cpu/ChangeLog: yyyy-mm-dd Stafford Horne <shorne@gmail.com> * or1korfpx.cpu (insn-opcode-float-regreg): Add SFUEQ_S, SFUNE_S, SFUGT_S, SFUGE_S, SFULT_S, SFULE_S, SFUN_S, SFUEQ_D, SFUNE_D, SFUGT_D, SFUGE_D, SFULT_D, SFULE_D, SFUN_D opcodes. (float-setflag-insn-base): New pmacro based on float-setflag-insn. (float-setflag-symantics, float-setflag-unordered-cmp-symantics, float-setflag-unordered-symantics): New pmacro for instruction symantics. (float-setflag-insn): Update to use float-setflag-insn-base. (float-setflag-unordered-insn): New pmacro for generating instructions.
387 lines
12 KiB
Scheme
387 lines
12 KiB
Scheme
; 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)
|
|
|
|
(dnop rDDF "or64 destination register (double floating point mode)" ((MACH ORFPX64-MACHS)) h-fdr f-r1)
|
|
(dnop rADF "or64 source register A (double floating point mode)" ((MACH ORFPX64-MACHS)) h-fdr f-r2)
|
|
(dnop rBDF "or64 source register B (double floating point mode)" ((MACH ORFPX64-MACHS)) h-fdr 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 -d)
|
|
(.str "lf." mnemonic ".d reg/reg/reg")
|
|
((MACH ORFPX64-MACHS))
|
|
(.str "lf." mnemonic ".d $rDDF,$rADF,$rBDF")
|
|
(+ OPC_FLOAT rDDF rADF rBDF (f-resv-10-3 0) (.sym OPC_FLOAT_REGREG_ (.upcase mnemonic) _D))
|
|
(set DF rDDF (mnemonic DF rADF rBDF))
|
|
()
|
|
)
|
|
(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-d
|
|
"lf.rem.d reg/reg/reg"
|
|
((MACH ORFPX64-MACHS))
|
|
"lf.rem.d $rDDF,$rADF,$rBDF"
|
|
(+ OPC_FLOAT rDDF rADF rBDF (f-resv-10-3 0) OPC_FLOAT_REGREG_REM_D)
|
|
(set DF rDDF (rem DF rADF rBDF))
|
|
()
|
|
)
|
|
|
|
(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-d
|
|
"lf.itof.d reg/reg"
|
|
((MACH ORFPX64-MACHS))
|
|
"lf.itof.d $rDDF,$rA"
|
|
(+ OPC_FLOAT rDDF rA (f-r3 0) (f-resv-10-3 0) OPC_FLOAT_REGREG_ITOF_D)
|
|
(set DF rDDF (float DF (get-rounding-mode) 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-d
|
|
"lf.ftoi.d reg/reg"
|
|
((MACH ORFPX64-MACHS))
|
|
"lf.ftoi.d $rD,$rADF"
|
|
(+ OPC_FLOAT rD rADF (f-r3 0) (f-resv-10-3 0) OPC_FLOAT_REGREG_FTOI_D)
|
|
(set WI rD (fix WI (get-rounding-mode) rADF))
|
|
()
|
|
)
|
|
|
|
(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- 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- mnemonic -d)
|
|
(.str "lf.sf" mnemonic ".d reg/reg")
|
|
((MACH ORFPX64-MACHS))
|
|
(.str "lf.sf" mnemonic ".d $rADF,$rBDF")
|
|
(+ OPC_FLOAT (f-r1 0) rADF rBDF (f-resv-10-3 0) (.sym OPC_FLOAT_REGREG_SF (.upcase mnemonic) _D))
|
|
(symantics rtx-mnemonic DF rADF rBDF)
|
|
()
|
|
)
|
|
(dni (.sym lf- 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-d
|
|
"lf.madd.d reg/reg/reg"
|
|
((MACH ORFPX64-MACHS))
|
|
"lf.madd.d $rDDF,$rADF,$rBDF"
|
|
(+ OPC_FLOAT rDDF rADF rBDF (f-resv-10-3 0) OPC_FLOAT_REGREG_MADD_D)
|
|
(set DF rDDF (add DF (mul DF rADF rBDF) rDDF))
|
|
()
|
|
)
|
|
|
|
(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 "-d")
|
|
(.str "lf.cust" cust-num ".d")
|
|
((MACH ORFPX64-MACHS))
|
|
(.str "lf.cust" cust-num ".d")
|
|
(+ OPC_FLOAT (f-resv-25-5 0) rADF rBDF (f-resv-10-3 0) (.sym "OPC_FLOAT_REGREG_CUST" cust-num "_D"))
|
|
(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")
|