Home | History | Annotate | Line # | Download | only in cpu
      1 ; OpenRISC 1000 architecture.  -*- Scheme -*-
      2 ; Copyright 2000-2019 Free Software Foundation, Inc.
      3 ; Contributed by Peter Gavin, pgavin (a] gmail.com
      4 ; Modified by Andrey Bacherov, avbacherov (a] 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