Home | History | Annotate | Download | only in cpu
      1 ; OpenRISC 1000 architecture.  -*- Scheme -*-
      2 ; Copyright 2000-2014 Free Software Foundation, Inc.
      3 ; Contributed by Peter Gavin, pgavin (a] gmail.com
      4 ;
      5 ; This program is free software; you can redistribute it and/or modify
      6 ; it under the terms of the GNU General Public License as published by
      7 ; the Free Software Foundation; either version 3 of the License, or
      8 ; (at your option) any later version.
      9 ;
     10 ; This program is distributed in the hope that it will be useful,
     11 ; but WITHOUT ANY WARRANTY; without even the implied warranty of
     12 ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13 ; GNU General Public License for more details.
     14 ;
     15 ; You should have received a copy of the GNU General Public License
     16 ; along with this program; if not, see <http://www.gnu.org/licenses/>
     17 
     18 ; Initial ORFPX32 instruction set
     19 
     20 ; I'm not sure how CGEN handles rounding in FP operations, except for
     21 ; in conversions to/from integers.  So lf.add, lf.sub, lf.mul, and
     22 ; lf.div do not round according to the FPCSR RM field.
     23 ; NaN, overflow, and underflow are not yet handled either.
     24 
     25 (define-normal-insn-enum insn-opcode-float-regreg
     26   "floating point reg/reg insn opcode enums" ()
     27   OPC_FLOAT_REGREG_ f-op-7-8
     28   (("ADD_S"  #x00)
     29    ("SUB_S"  #x01)
     30    ("MUL_S"  #x02)
     31    ("DIV_S"  #x03)
     32    ("ITOF_S" #x04)
     33    ("FTOI_S" #x05)
     34    ("REM_S"  #x06)
     35    ("MADD_S" #x07)
     36    ("SFEQ_S" #x08)
     37    ("SFNE_S" #x09)
     38    ("SFGT_S" #x0a)
     39    ("SFGE_S" #x0b)
     40    ("SFLT_S" #x0c)
     41    ("SFLE_S" #x0d)
     42    ("ADD_D"  #x10)
     43    ("SUB_D"  #x11)
     44    ("MUL_D"  #x12)
     45    ("DIV_D"  #x13)
     46    ("ITOF_D" #x14)
     47    ("FTOI_D" #x15)
     48    ("REM_D"  #x16)
     49    ("MADD_D" #x17)
     50    ("SFEQ_D" #x18)
     51    ("SFNE_D" #x19)
     52    ("SFGT_D" #x1a)
     53    ("SFGE_D" #x1b)
     54    ("SFLT_D" #x1c)
     55    ("SFLE_D" #x1d)
     56    ("CUST1_S" #xd0)
     57    ("CUST1_D" #xe0)
     58    )
     59   )
     60 
     61 (dnop rDSF "destination register (single floating point mode)" () h-fsr f-r1)
     62 (dnop rASF "source register A (single floating point mode)"    () h-fsr f-r2)
     63 (dnop rBSF "source register B (single floating point mode)"    () h-fsr f-r3)
     64 
     65 (dnop rDDF "destination register (double floating point mode)" ((MACH ORFPX64-MACHS)) h-fdr f-r1)
     66 (dnop rADF "source register A (double floating point mode)"    ((MACH ORFPX64-MACHS)) h-fdr f-r1)
     67 (dnop rBDF "source register B (double floating point mode)"    ((MACH ORFPX64-MACHS)) h-fdr f-r1)
     68 
     69 (define-pmacro (float-regreg-insn mnemonic)
     70   (begin
     71     (dni (.sym lf- mnemonic -s)
     72          (.str "lf." mnemonic ".s reg/reg/reg")
     73          ((MACH ORFPX-MACHS))
     74          (.str "lf." mnemonic ".s $rDSF,$rASF,$rBSF")
     75          (+ OPC_FLOAT rDSF rASF rBSF (f-resv-10-3 0) (.sym OPC_FLOAT_REGREG_ (.upcase mnemonic) _S))
     76          (set SF rDSF (mnemonic SF rASF rBSF))
     77          ()
     78          )
     79     (dni (.sym lf- mnemonic -d)
     80          (.str "lf." mnemonic ".d reg/reg/reg")
     81          ((MACH ORFPX64-MACHS))
     82          (.str "lf." mnemonic ".d $rDDF,$rADF,$rBDF")
     83          (+ OPC_FLOAT rDDF rADF rBDF (f-resv-10-3 0) (.sym OPC_FLOAT_REGREG_ (.upcase mnemonic) _D))
     84          (set DF rDDF (mnemonic DF rADF rBDF))
     85          ()
     86          )
     87     )
     88   )
     89 
     90 (float-regreg-insn add)
     91 (float-regreg-insn sub)
     92 (float-regreg-insn mul)
     93 (float-regreg-insn div)
     94 
     95 (dni lf-rem-s
     96      "lf.rem.s reg/reg/reg"
     97      ((MACH ORFPX-MACHS))
     98      "lf.rem.s $rDSF,$rASF,$rBSF"
     99      (+ OPC_FLOAT rDSF rASF rBSF (f-resv-10-3 0) OPC_FLOAT_REGREG_REM_S)
    100      (set SF rDSF (rem SF rASF rBSF))
    101      ()
    102      )
    103 (dni lf-rem-d
    104      "lf.rem.d reg/reg/reg"
    105      ((MACH ORFPX64-MACHS))
    106      "lf.rem.d $rDDF,$rADF,$rBDF"
    107      (+ OPC_FLOAT rDDF rADF rBDF (f-resv-10-3 0) OPC_FLOAT_REGREG_REM_D)
    108      (set DF rDDF (mod DF rADF rBDF))
    109      ()
    110      )
    111 
    112 (define-pmacro (get-rounding-mode)
    113   (case INT sys-fpcsr-rm
    114         ((0) 1) ; TIES-TO-EVEN -- I'm assuming this is what is meant by "round to nearest"
    115         ((1) 3) ; TOWARD-ZERO
    116         ((2) 4) ; TOWARD-POSITIVE
    117         (else 5) ; TOWARD-NEGATIVE
    118         )
    119   )
    120 
    121 (dni lf-itof-s
    122      "lf.itof.s reg/reg"
    123      ((MACH ORFPX-MACHS))
    124      "lf.itof.s $rDSF,$rA"
    125      (+ OPC_FLOAT rDSF rA (f-r3 0) (f-resv-10-3 0) OPC_FLOAT_REGREG_ITOF_S)
    126      (set SF rDSF (float SF (get-rounding-mode) (trunc SI rA)))
    127      ()
    128      )
    129 (dni lf-itof-d
    130      "lf.itof.d reg/reg"
    131      ((MACH ORFPX64-MACHS))
    132      "lf.itof.d $rDSF,$rA"
    133      (+ OPC_FLOAT rDSF rA (f-r3 0) (f-resv-10-3 0) OPC_FLOAT_REGREG_ITOF_D)
    134      (set DF rDDF (float DF (get-rounding-mode) rA))
    135      ()
    136      )
    137 
    138 (dni lf-ftoi-s
    139      "lf.ftoi.s reg/reg"
    140      ((MACH ORFPX-MACHS))
    141      "lf.ftoi.s $rD,$rASF"
    142      (+ OPC_FLOAT rD rASF (f-r3 0) (f-resv-10-3 0) OPC_FLOAT_REGREG_FTOI_S)
    143      (set WI rD (ext WI (fix SI (get-rounding-mode) rASF)))
    144      ()
    145      )
    146 
    147 (dni lf-ftoi-d
    148      "lf.ftoi.d reg/reg"
    149      ((MACH ORFPX64-MACHS))
    150      "lf.ftoi.d $rD,$rADF"
    151      (+ OPC_FLOAT rD rADF (f-r3 0) (f-resv-10-3 0) OPC_FLOAT_REGREG_FTOI_D)
    152      (set DI rD (fix DI (get-rounding-mode) rADF))
    153      ()
    154      )
    155 
    156 (define-pmacro (float-setflag-insn mnemonic)
    157   (begin
    158     (dni (.sym lf- mnemonic -s)
    159          (.str "lf.sf" mnemonic ".s reg/reg")
    160          ((MACH ORFPX-MACHS))
    161          (.str "lf.sf" mnemonic ".s $rASF,$rBSF")
    162          (+ OPC_FLOAT (f-r1 0) rASF rBSF (f-resv-10-3 0) (.sym OPC_FLOAT_REGREG_SF (.upcase mnemonic) _S))
    163          (set BI sys-sr-f (mnemonic SF rASF rBSF))
    164          ()
    165          )
    166     (dni (.sym lf- mnemonic -d)
    167          (.str "lf.sf" mnemonic ".d reg/reg")
    168          ((MACH ORFPX64-MACHS))
    169          (.str "lf.sf" mnemonic ".d $rASF,$rBSF")
    170          (+ OPC_FLOAT (f-r1 0) rASF rBSF (f-resv-10-3 0) (.sym OPC_FLOAT_REGREG_SF (.upcase mnemonic) _D))
    171          (set BI sys-sr-f (mnemonic DF rADF rBDF))
    172          ()
    173          )
    174     )
    175   )
    176 
    177 (float-setflag-insn eq)
    178 (float-setflag-insn ne)
    179 (float-setflag-insn ge)
    180 (float-setflag-insn gt)
    181 (float-setflag-insn lt)
    182 (float-setflag-insn le)
    183 
    184 (dni lf-madd-s
    185      "lf.madd.s reg/reg/reg"
    186      ((MACH ORFPX-MACHS))
    187      "lf.madd.s $rDSF,$rASF,$rBSF"
    188      (+ OPC_FLOAT rDSF rASF rBSF (f-resv-10-3 0) OPC_FLOAT_REGREG_MADD_S)
    189      (set SF rDSF (add SF (mul SF rASF rBSF) rDSF))
    190      ()
    191      )
    192 (dni lf-madd-d
    193      "lf.madd.d reg/reg/reg"
    194      ((MACH ORFPX64-MACHS))
    195      "lf.madd.d $rDDF,$rADF,$rBDF"
    196      (+ OPC_FLOAT rDDF rADF rBDF (f-resv-10-3 0) OPC_FLOAT_REGREG_MADD_D)
    197      (set DF rDDF (add DF (mul DF rADF rBDF) rDDF))
    198      ()
    199      )
    200 
    201 (define-pmacro (float-cust-insn cust-num)
    202   (begin
    203     (dni (.sym "lf-cust" cust-num "-s")
    204          (.str "lf.cust" cust-num ".s")
    205          ((MACH ORFPX-MACHS))
    206          (.str "lf.cust" cust-num ".s $rASF,$rBSF")
    207          (+ OPC_FLOAT (f-resv-25-5 0) rASF rBSF (f-resv-10-3 0) (.sym "OPC_FLOAT_REGREG_CUST" cust-num "_S"))
    208          (nop)
    209          ()
    210          )
    211     (dni (.sym "lf-cust" cust-num "-d")
    212          (.str "lf.cust" cust-num ".d")
    213          ((MACH ORFPX64-MACHS))
    214          (.str "lf.cust" cust-num ".d")
    215          (+ OPC_FLOAT (f-resv-25-5 0) rADF rBDF (f-resv-10-3 0) (.sym "OPC_FLOAT_REGREG_CUST" cust-num "_D"))
    216          (nop)
    217          ()
    218          )
    219     )
    220   )
    221 
    222 (float-cust-insn "1")
    223