OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-binutils/] [binutils-2.19.1/] [cgen/] [cpu/] [sparccom.cpu] - Rev 6

Compare with Previous | Blame | View Log

; SPARC 32/64 CPU description.  -*- Scheme -*-
; This file contains instructions common to both sparc32/sparc64.
; It also contains sparc32/64 specific insns, but only when they are a variant
; of a collection of common ones.
; Copyright (C) 2000 Red Hat, Inc.
; This file is part of CGEN.
; See file COPYING.CGEN for details.

; Notes:
; - sparc64 support wip
; - fp support todo
; - source file layout wip
; - cpu family layout wip

; Lots of sparc insns have either reg/reg or reg/simm13 cases.  */

(define-pmacro (op3-reg-fmt op3-code)
  (+ OP_2 op3-code rd rs1 rs2 (f-i 0) (f-res-asi 0))
)
(define-pmacro (op3-imm-fmt op3-code)
  (+ OP_2 op3-code rd rs1 (f-i 1) simm13)
)

; Load/Store ops

(define-pmacro (ld-op name comment attrs op3 mode dest)
  (begin
    (dnmi (.sym name "-reg+g0") comment attrs
          (.str name " [$rs1],$" dest)
          (emit (.sym name -reg+reg) rs1 (rs2 0) dest))
    (dnmi (.sym name "-reg+0") comment attrs
          (.str name " [$rs1],$" dest)
          (emit (.sym name -reg+imm) rs1 (simm13 0) dest))
    (dni (.sym name "-reg+reg") comment attrs
         (.str name " [$rs1+$rs2],$" dest)
         (+ OP_3 op3 dest rs1 (f-i 0) (f-res-asi 0) rs2)
         (set mode dest (mem mode (add WI rs1 rs2)))
         ())
    (dni (.sym name "-reg+imm") comment attrs
         (.str name " [$rs1+$simm13],$" dest)
         (+ OP_3 op3 dest rs1 (f-i 1) simm13)
         (set mode dest (mem mode (add WI rs1 simm13)))
         ())
    (dnmi (.sym name "-reg/asi") comment attrs
          (.str name " [$rs1]$asi,$" dest)
          (emit (.sym name -reg+reg/asi) rs1 (rs2 0) asi dest))
    (dni (.sym name "-reg+reg/asi") comment attrs
         (.str name " [$rs1+$rs2]$asi,$" dest)
         (+ OP_3 (.sym op3 A) dest rs1 (f-i 0) asi rs2)
         (set mode dest (mem mode (add WI rs1 rs2)))
         ())
    )
)
(ld-op ldsb "load signed byte"       ()         OP3_LDSB QI  rd)
(ld-op ldub "load unsigned byte"     ()         OP3_LDUB UQI rd)
(ld-op ldsh "load signed halfword"   ()         OP3_LDSH HI  rd)
(ld-op lduh "load unsigned halfword" ()         OP3_LDUH UHI rd)
(ld-op ldsw "load signed word"       ()         OP3_LDSW SI  rd)
(ld-op lduw "load unsigned word"     ()         OP3_LDUW USI rd)
(ld-op ldx  "load extended word"     ((MACH64)) OP3_LDX  DI  rd)

; Aliases are treated as such (ALIAS attribute) so we can use ld-op.
; ??? Perhaps lduw should be the alias.  Let's leave it like this for now.
(ld-op ld   "load word"              (ALIAS)  OP3_LDUW SI  rd)

; ??? This would work with special operand get/set support but
; it's not clear this case justifies implementing that yet.
;(ld-op ldd  "load double reg"        ()       OP3_LDD  DI  rdd)

(dnmi ldd-reg+g0 "load double reg, reg+g0" ()
      "ldd [$rs1],$rdd"
      (emit ldd-reg+reg rs1 (rs2 0) rdd)
)
(dnmi ldd-reg+0 "load double reg, reg+0" ()
      "ldd [$rs1],$rdd"
      (emit ldd-reg+imm rs1 (simm13 0) rdd)
)
(dni ldd-reg+reg "load double reg, reg+reg" ()
     "ldd [$rs1+$rs2],$rdd"
     (+ OP_3 OP3_LDD rdd rs1 (f-i 0) (f-res-asi 0) rs2)
     (sequence ((DI temp))
               (set temp (mem DI (add WI rs1 rs2)))
               (set rdd (subword SI temp (const 0)))
               (set (reg h-gr (add (regno rdd) (const 1)))
                    (subword SI temp (const 1))))
     ()
)
(dni ldd-reg+imm "load double reg, reg+imm" ()
     "ldd [$rs1+$simm13],$rdd"
     (+ OP_3 OP3_LDD rdd rs1 (f-i 1) simm13)
     (sequence ()
               (set rdd (mem SI (add WI rs1 simm13)))
               (set (reg h-gr (add (regno rdd) (const 1)))
                    (mem SI (add rs1 (add simm13 (const 4))))))
     ()
)
(dnmi ldd-reg/asi "load double reg, reg+g0/asi" ()
      "ldd [$rs1]$asi,$rdd"
      (emit ldd-reg+reg/asi rs1 (rs2 0) asi rdd)
)
(dni ldd-reg+reg/asi "load double reg, reg+reg/asi" ()
     "ldd [$rs1+$rs2]$asi,$rdd"
     (+ OP_3 OP3_LDDA rdd rs1 (f-i 0) asi rs2)
     (sequence ()
               (set rdd (mem SI (add WI rs1 rs2)))
               (set (reg h-gr (add (regno rdd) (const 1)))
                    (mem SI (add rs1 (add rs2 (const 4))))))
     ()
)

(define-pmacro (st-op name comment attrs op3 mode src)
  (begin
    (dnmi (.sym name "-reg+g0") comment attrs
          (.str name " $" src ",[$rs1]")
          (emit (.sym name -reg+reg) src rs1 (rs2 0)))
    (dnmi (.sym name "-reg+0") comment attrs
          (.str name " $" src ",[$rs1]")
          (emit (.sym name -reg+imm) src rs1 (simm13 0)))
    (dni (.sym name "-reg+reg") comment attrs
         (.str name " $" src ",[$rs1+$rs2]")
         (+ OP_3 op3 src rs1 (f-i 0) (f-res-asi 0) rs2)
         (set mode (mem mode (add WI rs1 rs2)) src)
         ())
    (dni (.sym name "-reg+imm") comment attrs
         (.str name " $" src ",[$rs1+$simm13]")
         (+ OP_3 op3 src rs1 (f-i 1) simm13)
         (set mode (mem mode (add WI rs1 simm13)) src)
         ())
    (dnmi (.sym name "-reg/asi") comment attrs
          (.str name " $" src ",[$rs1]$asi")
          (emit (.sym name -reg+reg/asi) src rs1 (rs2 0) asi))
    (dni (.sym name "-reg+reg/asi") comment attrs
         (.str name " $" src ",[$rs1+$rs2]$asi")
         (+ OP_3 (.sym op3 A) src rs1 (f-i 0) asi rs2)
         (set mode (mem mode (add WI rs1 rs2)) src)
         ())
    )
)
(st-op stb "store byte"          ()       OP3_STB QI rd)
(st-op sth "store halfword"      ()       OP3_STH HI rd)
(st-op st  "store word"          ()       OP3_STW SI rd)
(st-op stx "store extended word" ((MACH64)) OP3_STX DI rd)

; ??? This would work with special operand get/set support but
; it's not clear this case justifies implementing that yet.
;(st-op std "store double reg"    ()       OP3_STD DI rdd)

(dnmi std-reg+g0 "store double reg, reg+g0" ()
      "std $rdd,[$rs1]"
      (emit std-reg+reg rdd rs1 (rs2 0))
)
(dnmi std-reg+0 "store double reg, reg+0" ()
      "std $rdd,[$rs1]"
      (emit std-reg+imm rdd rs1 (simm13 0))
)
(dni std-reg+reg "store double reg, reg+reg" ()
     "std $rdd,[$rs1+$rs2]"
     (+ OP_3 OP3_STD rdd rs1 (f-i 0) (f-res-asi 0) rs2)
     (sequence ()
               (set (mem SI (add rs1 rs2)) rdd)
               (set (mem SI (add rs1 (add rs2 (const 4))))
                    (reg h-gr (add (regno rdd) (const 1)))))
     ()
)
(dni std-reg+imm "store double reg, reg+imm" ()
     "std $rdd,[$rs1+$simm13]"
     (+ OP_3 OP3_STD rdd rs1 (f-i 1) simm13)
     (sequence ()
               (set (mem SI (add rs1 simm13)) rdd)
               (set (mem SI (add rs1 (add simm13 (const 4))))
                    (reg h-gr (add (regno rdd) (const 1)))))
     ()
)
(dnmi std-reg/asi "store double reg, reg+g0/asi" ()
      "std $rdd,[$rs1]$asi"
      (emit std-reg+reg/asi rdd rs1 (rs2 0) asi)
)
(dni std-reg+reg/asi "store double reg, reg+reg/asi" ()
     "std $rdd,[$rs1+$rs2]$asi"
     (+ OP_3 OP3_STDA rdd rs1 (f-i 0) asi rs2)
     (sequence ()
               (set (mem SI (add rs1 rs2)) rdd)
               (set (mem SI (add rs1 (add rs2 (const 4))))
                    (reg h-gr (add (regno rdd) (const 1)))))
     ()
)

; nop
; A nop is defined to be a sethi of %g0.
; This needn't be a macro-insn, but making it one greatly simplifies decode.c
; as code needn't be generated to confirm hi22 == 0.
; On the other hand spending a little time in the decoder is often worth it.

(dnmi nop "nop"
      ()
      "nop"
      (emit sethi (rd 0) (hi22 0))
)

; sethi

(dni sethi "sethi" ()
     "sethi $hi22,$rd"
     (+ OP_0 rd OP2_SETHI hi22)
     (set rd (sll USI hi22 (const 10))) ; (set SI rd hi22)
     ()
)

; Add/Subtract

(define-pmacro (s32-set-addc-flags a b carry)
  (sequence ((SI x))
            (set x (addc a b carry))
            (set icc-c (add-cflag a b carry))
            (set icc-v (add-oflag a b carry))
            (set icc-n (nflag x))
            (set icc-z (zflag x)))
)
(define-pmacro (s32-set-subc-flags a b carry)
  (sequence ((SI x))
            (set x (subc a b carry))
            (set icc-c (sub-cflag a b carry))
            (set icc-v (sub-oflag a b carry))
            (set icc-n (nflag x))
            (set icc-z (zflag x)))
)

(define-pmacro (s64-set-addc-flags a b carry)
  (sequence ((SI x32) (DI x))
            (set x (addc a b carry))
            (set x32 x)
            (set icc-c (add-cflag SI a b carry))
            (set icc-v (add-oflag SI a b carry))
            (set icc-n (nflag x32))
            (set icc-z (zflag x32))
            (set xcc-c (add-cflag a b carry))
            (set xcc-v (add-oflag a b carry))
            (set xcc-n (nflag x))
            (set xcc-z (zflag x)))
)
(define-pmacro (s64-set-subc-flags a b carry)
  (sequence ((SI x32) (DI x))
            (set x (subc a b carry))
            (set x32 x)
            (set icc-c (sub-cflag SI a b carry))
            (set icc-v (sub-oflag SI a b carry))
            (set icc-n (nflag x32))
            (set icc-z (zflag x32))
            (set xcc-c (sub-cflag a b carry))
            (set xcc-v (sub-oflag a b carry))
            (set xcc-n (nflag x))
            (set xcc-z (zflag x)))
)

(define-pmacro (arith-binop name comment page attrs op3 sem-op)
  (begin
    (dni name
         (.str comment ", " page)
         attrs
         (.str name " $rs1,$rs2,$rd")
         (+ OP_2 op3 rd rs1 rs2 (f-i 0) (f-res-asi 0))
         (set rd (sem-op rs1 rs2))
         ())
    (dni (.sym name -imm)
         (.str comment " immediate, " page)
         attrs
         (.str name " $rs1,$simm13,$rd")
         (+ OP_2 op3 rd rs1 (f-i 1) simm13)
         (set rd (sem-op rs1 simm13))
         ())
    )
)
(define-pmacro (arith-cc-binop name comment page attrs op3 sem-op
                               s32-set-flags s64-set-flags)
  (begin
    (dni name
         (.str comment ", setting cc, " page)
         attrs
         (.str name " $rs1,$rs2,$rd")
         (+ OP_2 op3 rd rs1 rs2 (f-i 0) (f-res-asi 0))
         (sequence ()
                   (if (eq-attr (current-mach) ARCH64 TRUE)
                       (s64-set-flags rs1 rs2 (const 0))
                       (s32-set-flags rs1 rs2 (const 0)))
                   (set rd (sem-op rs1 rs2))
                   )
         ())
    (dni (.sym name -imm)
         (.str comment " immediate, setting cc, " page)
         attrs
         (.str name " $rs1,$simm13,$rd")
         (+ OP_2 op3 rd rs1 (f-i 1) simm13)
         (sequence ()
                   (if (eq-attr (current-mach) ARCH64 TRUE)
                       (s64-set-flags rs1 simm13 (const 0))
                       (s32-set-flags rs1 simm13 (const 0)))
                   (set rd (sem-op rs1 simm13))
                   )
         ())
    )
)
(arith-binop add "add" "v8 page ??, v9 page 135" () OP3_ADD add)
(arith-binop sub "subtract" "v8 page ??, v9 page 230" () OP3_SUB sub)
(arith-cc-binop addcc "add" "v8 page ??, v9 page 135" () OP3_ADDCC add
                s32-set-addc-flags s64-set-addc-flags)
(arith-cc-binop subcc "subtract" "v8 page ??, v9 page 230" () OP3_SUBCC sub
                s32-set-subc-flags s64-set-subc-flags)

; Same except include carry bit.

(define-pmacro (arith-carry-binop name comment page attrs op3 sem-op)
  (begin
    (dni name
         (.str comment " with carry, " page)
         attrs
         (.str name " $rs1,$rs2,$rd")
         (+ OP_2 op3 rd rs1 rs2 (f-i 0) (f-res-asi 0))
         (set rd (sem-op rs1 rs2 icc-c))
         ())
    (dni (.sym name -imm)
         (.str comment " immediate with carry, " page)
         attrs
         (.str name " $rs1,$simm13,$rd")
         (+ OP_2 op3 rd rs1 (f-i 1) simm13)
         (set rd (sem-op rs1 simm13 icc-c))
         ())
    )
)
(define-pmacro (arith-carry-cc-binop name comment page attrs op3 sem-op set-flags)
  (begin
    (dni name
         (.str comment " with carry, setting cc, " page)
         attrs
         (.str name " $rs1,$rs2,$rd")
         (+ OP_2 op3 rd rs1 rs2 (f-i 0) (f-res-asi 0))
         (sequence ()
                   (set-flags rs1 rs2 icc-c)
                   (set rd (sem-op rs1 rs2 icc-c))
                   )
         ())
    (dni (.sym name -imm)
         (.str comment " immediate with carry, setting cc, " page)
         attrs
         (.str name " $rs1,$simm13,$rd")
         (+ OP_2 op3 rd rs1 (f-i 1) simm13)
         (sequence ()
                   (set-flags rs1 simm13 icc-c)
                   (set rd (sem-op rs1 simm13 icc-c))
                   )
         ())
    )
)
; mach32 versions
(arith-carry-binop addx "add" "v8 page ??" ((MACH32)) OP3_ADDX addc)
(arith-carry-binop subx "subtract" "v8 page ??" ((MACH32)) OP3_SUBX subc)
(arith-carry-cc-binop addxcc "add" "v8 page ??" ((MACH32)) OP3_ADDXCC addc
                      s32-set-addc-flags)
(arith-carry-cc-binop subxcc "subtract" "v8 page ??" ((MACH32)) OP3_SUBXCC subc
                      s32-set-subc-flags)
; mach64 versions
; same as mach32 except mnemonic is different
(arith-carry-binop addc "add" "v9 page 135" ((MACH64)) OP3_ADDC addc)
(arith-carry-binop subc "subtract" "v9 page 230" ((MACH64)) OP3_SUBC subc)
(arith-carry-cc-binop addccc "add" "v9 page 135" ((MACH64)) OP3_ADDCCC addc
                      s64-set-addc-flags)
(arith-carry-cc-binop subccc "subtract" "v9 page 230" ((MACH64)) OP3_SUBCCC subc
                      s64-set-subc-flags)

; Binary boolean ops

(define-pmacro (s32-set-bool-flags x)
  (sequence ()
            (set icc-z (zflag x))
            (set icc-n (nflag x))
            (set icc-c (const 0))
            (set icc-v (const 0))
            )
)
(define-pmacro (s64-set-bool-flags x)
  (sequence ()
            (set icc-z (zflag (trunc SI x)))
            (set icc-n (nflag (trunc SI x)))
            (set icc-c (const 0))
            (set icc-v (const 0))
            (set xcc-z (zflag x))
            (set xcc-n (nflag x))
            (set xcc-c (const 0))
            (set xcc-v (const 0))
            )
)

(define-pmacro (bool-binop name page op3 sem-op)
  (begin
    (dni name (.str name ", " page) ()
         (.str name " $rs1,$rs2,$rd")
         (+ OP_2 op3 rd rs1 rs2 (f-i 0) (f-res-asi 0))
         (set rd (sem-op rs1 rs2))
         ())
    (dni (.sym name -imm) (.str name " immediate, " page) ()
         (.str name " $rs1,$simm13,$rd")
         (+ OP_2 op3 rd rs1 (f-i 1) simm13)
         (set rd (sem-op rs1 simm13))
         ())
    (dni (.sym name cc) (.str name ", setting cc, " page) ()
         (.str name "cc $rs1,$rs2,$rd")
         (+ OP_2 (.sym op3 CC) rd rs1 rs2 (f-i 0) (f-res-asi 0))
         (sequence ()
                   (if (eq-attr (current-mach) ARCH64 TRUE)
                       (s64-set-bool-flags (sem-op rs1 rs2))
                       (s32-set-bool-flags (sem-op rs1 rs2)))
                   (set rd (sem-op rs1 rs2))
                   )
         ())
    (dni (.sym name cc-imm) (.str name " immediate, setting cc, " page) ()
         (.str name "cc $rs1,$simm13,$rd")
         (+ OP_2 (.sym op3 CC) rd rs1 (f-i 1) simm13)
         (sequence ()
                   (if (eq-attr (current-mach) ARCH64 TRUE)
                       (s64-set-bool-flags (sem-op rs1 simm13))
                       (s32-set-bool-flags (sem-op rs1 simm13)))
                   (set rd (sem-op rs1 simm13))
                   )
         ())
    )
)
(bool-binop and "v9 page 181" OP3_AND and)
(bool-binop or  "v9 page 181" OP3_OR  or)
(bool-binop xor "v9 page 181" OP3_XOR xor)

; Early experiments.
;(dsmn (andn a b) (list 'and a (list 'inv b)))
;(dsmn (orn a b) (list 'or a (list 'inv b)))
;(dsmn (xorn a b) (list 'xor a (list 'inv b)))

(define-pmacro (sem-andn a b) (and a (inv b)))
(define-pmacro (sem-orn a b) (or a (inv b)))
(define-pmacro (sem-xorn a b) (xor a (inv b)))

(bool-binop andn "v9 page 181" OP3_ANDN sem-andn)
(bool-binop orn  "v9 page 181" OP3_ORN  sem-orn)
(bool-binop xnor "v9 page 181" OP3_XNOR sem-xorn)

; Shifts

(define-pmacro (shift-binop name comment op3 sem-op)
  (begin
     (dni name comment ()
          (.str name " $rs1,$rs2,$rd")
          (+ OP_2 op3 rd rs1 rs2 (f-i 0) (f-res-asi 0))
          (set rd (sem-op rs1 (and rs2 (const 31))))
          ())
     (dni (.sym name -imm) (.str comment -imm) ()
          (.str name " $rs1,$simm13,$rd")
          (+ OP_2 op3 rd rs1 (f-i 1) simm13)
          ; ??? v9 uses only the low bits.  v8?
          (set rd (sem-op rs1 (and simm13 (const 31))))
          ())
     )
)
(shift-binop sll "shift left logical" OP3_SLL sll)
(shift-binop srl "shift right logical" OP3_SRL srl)
(shift-binop sra "shift right arithmetic" OP3_SRA sra)

; Multiply/Divide

(define-pmacro (mult-binop name comment op3 sem-op ext-op)
  (begin
     (dni name comment ()
          (.str name " $rs1,$rs2,$rd")
          (+ OP_2 op3 rd rs1 rs2 (f-i 0) (f-res-asi 0))
          (sequence ((DI res))
                    (set res (sem-op (ext-op DI rs1) (ext-op DI rs2)))
                    (set (reg WI h-y) (trunc SI (srl res (const 32))))
                    (set rd (trunc SI res))
                    )
          ())
     (dni (.sym name -imm) (.str comment -imm) ()
          (.str name " $rs1,$simm13,$rd")
          (+ OP_2 op3 rd rs1 (f-i 1) simm13)
          (sequence ((DI res))
                    (set res (sem-op (ext-op DI rs1) (ext-op DI simm13)))
                    (set (reg WI h-y) (trunc SI (srl res (const 32))))
                    (set rd (trunc SI res))
                    )
          ())
     (dni (.sym name -cc) (.str comment -cc) ()
          (.str name "cc $rs1,$rs2,$rd")
          (+ OP_2 (.sym op3 CC) rd rs1 rs2 (f-i 0) (f-res-asi 0))
          (sequence ((DI res))
                    (set res (sem-op (ext-op DI rs1) (ext-op DI rs2)))
                    (set (reg WI h-y) (trunc SI (srl res (const 32))))
                    (set rd (trunc SI res))
                    ; We use bool-flags here 'cus it works (FIXME:revisit).
                    ; We can't use rd here 'cus it might be %g0.
                    (s32-set-bool-flags (trunc SI res))
                    )
          ())
     (dni (.sym name -cc-imm) (.str comment -cc-imm) ()
          (.str name "cc $rs1,$simm13,$rd")
          (+ OP_2 (.sym op3 CC) rd rs1 (f-i 1) simm13)
          (sequence ((DI res))
                    (set res (sem-op (ext-op DI rs1) (ext-op DI simm13)))
                    (set (reg WI h-y) (trunc SI (srl res (const 32))))
                    (set rd (trunc SI res))
                    ; We use bool-flags here 'cus it works (FIXME:revisit).
                    ; We can't use rd here 'cus it might be %g0.
                    (s32-set-bool-flags (trunc SI res))
                    )
          ())
     )
)
(mult-binop smul "smul" OP3_SMUL mul ext)
(mult-binop umul "umul" OP3_UMUL mul zext)

(define-pmacro (div-binop name comment mach-attrs op3 sem-op ext-op set-flags)
  (begin
    (dni name (.str comment ", v9 page 152") ((mach-attrs))
         (.str name " $rs1,$rs2,$rd")
         (+ OP_2 op3 rd rs1 rs2 (f-i 0) (f-res-asi 0))
         (sequence ((DI dividend))
                   (set dividend (join DI SI (reg SI h-y) rs1))
                   (set rd (trunc SI (sem-op dividend (ext-op DI rs2))))
                   ; FIXME: Overflow,etc. handling.
                   )
         ())
    (dni (.sym name -imm) (.str comment -imm ", v9 page 152") ((mach-attrs))
         (.str name " $rs1,$simm13,$rd")
         (+ OP_2 op3 rd rs1 (f-i 1) simm13)
         (sequence ((DI dividend))
                   (set dividend (join DI SI (reg SI h-y) rs1))
                   (set rd (trunc SI (sem-op dividend (ext-op DI simm13))))
                   ; FIXME: Overflow,etc. handling.
                   )
         ())
    (dni (.sym name -cc) (.str comment -cc ", v9 page 152") ((mach-attrs))
         (.str name "cc $rs1,$rs2,$rd")
         (+ OP_2 (.sym op3 CC) rd rs1 rs2 (f-i 0) (f-res-asi 0))
         (sequence ((DI dividend))
                   (set dividend (join DI SI (reg SI h-y) rs1))
                   (set rd (trunc SI (sem-op dividend (ext-op DI rs2))))
                   ; FIXME: Overflow,etc. handling.
                   set-flags
                   )
         ())
    (dni (.sym name -cc-imm) (.str comment -cc-imm ", v9 page 152") ((mach-attrs))
         (.str name "cc $rs1,$simm13,$rd")
         (+ OP_2 (.sym op3 CC) rd rs1 (f-i 1) simm13)
         (sequence ((DI dividend))
                   (set dividend (join DI SI (reg SI h-y) rs1))
                   (set rd (trunc SI (sem-op dividend (ext-op DI simm13))))
                   ; FIXME: Overflow,etc. handling.
                   set-flags
                   )
         ())
    )
)
(div-binop sdiv "sdiv" MACH32 OP3_SDIV div ext (s32-set-bool-flags rd))
(div-binop udiv "udiv" MACH32 OP3_UDIV div zext (s32-set-bool-flags rd))

; Multiply/Step

(dni mulscc "multiply step" ()
     "mulscc $rs1,$rs2,$rd"
     (+ OP_2 OP3_MULSCC rd rs1 rs2 (f-i 0) (f-res-asi 0))
     (sequence ((SI tmp) (SI add-tmp) (SI rd-tmp))
               ; v8 page 112, step 2
               (set tmp (srl SI rs1 (const 1)))
               (if (ne (xor BI (reg BI h-icc-n) (reg BI h-icc-v))
                       (const 0))
                   (set tmp (or SI tmp (const SI #x80000000))))
               ; step 3
               (if (ne (and SI (reg SI h-y) (const 1)) (const 0))
                   (set add-tmp rs2)
                   (set add-tmp (const 0)))
               ; step 4
               (set rd-tmp (add tmp add-tmp))
               ; step 5
               (s32-set-addc-flags tmp add-tmp (const 0))
               ;(set (reg UQI h-cc) (addc-cc tmp add-tmp (const 0)))
               ; step 6
               (set (reg SI h-y) (srl SI (reg SI h-y) (const 1)))
               (if (ne (and SI rs1 (const 1)) (const 0))
                   (set (reg SI h-y) (or SI (reg SI h-y) (const SI #x80000000))))
               ; rd first created in rd-tmp so step 6 gets right value for rs1
               (set SI rd rd-tmp)
               )
     ()
)

; Window ops
; V8 page 117

(define-pmacro (window-binop name comment op3 handler)
  (begin
     (dni name comment ()
          (.str name " $rs1,$rs2,$rd")
          (+ OP_2 op3 rd rs1 rs2 (f-i 0) (f-res-asi 0))
          (set rd (c-call WI handler pc rs1 rs2))
          ())
     (dni (.sym name -imm) (.str comment -imm) ()
          (.str name " $rs1,$simm13,$rd")
          (+ OP_2 op3 rd rs1 (f-i 1) simm13)
          (set rd (c-call WI handler pc rs1 simm13))
          ())
     )
)
(window-binop save "save caller's window" OP3_SAVE "@cpu@_do_save")
(window-binop restore "restore caller's window" OP3_RESTORE "@cpu@_do_restore")

; Trap stuff

(dni rett "return from trap" ()
     "rett $rs1,$rs2"
     (+ OP_2 OP3_RETT (f-rd 0) rs1 rs2 (f-i 0) (f-res-asi 0))
     (delay (const 1)
            (set pc (c-call WI "@cpu@_do_rett" pc rs1 rs2)))
     ()
)
(dni rett-imm "return from trap, immediate" ()
     "rett $rs1,$simm13"
     (+ OP_2 OP3_RETT (f-rd 0) rs1 (f-i 1) simm13)
     (delay (const 1)
            (set pc (c-call WI "@cpu@_do_rett" pc rs1 simm13)))
     ()
)

; Misc.

(dni unimp "unimplemented" ()
     "unimp $imm22"
     (+ OP_0 (f-rd-res 0) OP2_UNIMP imm22)
     (c-call VOID "@arch@_do_unimp" pc imm22)
     ()
)

; Subroutine calls, returns.

(dnmi call-reg,0 "call reg,0" ()
     "call $rs1,0" ; FIXME: what's the ,0 suffix for?
     (emit jmpl rs1 (rd 15) (rs2 0))
)

(dnmi call-reg "call reg" ()
     "call $rs1"
     (emit jmpl rs1 (rd 15) (rs2 0))
)

(dnmi call,0 "call,0" ()
     "call $disp30,0" ; FIXME: what's the ,0 suffix for?
     (emit call disp30)
)

(dni call "call" (DELAY-SLOT)
     "call $disp30"
     (+ OP_1 disp30)
     (sequence ()
               (set (reg h-gr 15) pc)
               (delay (const 1)
                      (set pc disp30)))
     ()
)

(dni jmpl "jmpl" (DELAY-SLOT)
     "jmpl $rs1+$rs2,$rd"
     (op3-reg-fmt OP3_JMPL)
     (sequence ()
               (set rd pc)
               (delay (const 1)
                      (set pc (add WI rs1 rs2))))
     ()
)

(dni jmpl-imm "jmpl" (DELAY-SLOT)
     "jmpl $rs1+$simm13,$rd"
     (op3-imm-fmt OP3_JMPL)
     (sequence ()
               (set rd pc)
               (delay (const 1)
                      (set pc (add WI rs1 simm13))))
     ()
)

;(dsn (icc-op op) (cx:make BI (string-append "icc (" op ")")))
;(dsn (icc-op op) (list 'c-call: 'BI "icc" (reg UQI h-cc) (.str op)))
;(dsmn (icc-op op) (list 'c-call: 'BI "icc" '(reg UQI h-cc) (.str op)))
;(define-pmacro (icc-op op) (c-call BI "icc" (reg UQI h-cc) (.str op)))

; Branches

(define-pmacro (bicc-branch bname tname comment cond test br-sem)
  (begin
    (dni bname (.str "branch " comment) (V9-DEPRECATED)
         (.str bname "$a $disp22")
         (+ OP_0 a cond OP2_BICC disp22)
         (br-sem test icc)
         ())
    (dni tname (.str "trap " comment) (TRAP)
         (.str tname " $rs1,$rs2")
         (+ OP_2 (f-a 0) cond (f-op3 #x3a) rs1 (f-i 0) (f-res-asi 0) rs2)
         (if (test icc)
             (set pc (c-call IAI "@cpu@_sw_trap" pc rs1 rs2)))
          ())
    (dni (.sym tname -imm) (.str "trap-imm " comment) (TRAP)
          (.str tname " $rs1,$simm13")
          (+ OP_2 (f-a 0) cond (f-op3 #x3a) rs1 (f-i 1) simm13)
          (if (test icc)
              (set pc (c-call IAI "@cpu@_sw_trap" pc rs1 simm13)))
          ())
    )
)
; test-*,uncond-br-sem,cond-br-sem are defined in sparc.cpu.
(bicc-branch ba   ta   "always" CC_A   test-always uncond-br-sem)
(bicc-branch bn   tn   "never"  CC_N   test-never uncond-br-sem)
(bicc-branch bne  tne  "ne"     CC_NE  test-ne cond-br-sem)
(bicc-branch be   te   "eq"     CC_E   test-eq cond-br-sem)
(bicc-branch bg   tg   "gt"     CC_G   test-gt cond-br-sem)
(bicc-branch ble  tle  "le"     CC_LE  test-le cond-br-sem)
(bicc-branch bge  tge  "ge"     CC_GE  test-ge cond-br-sem)
(bicc-branch bl   tl   "lt"     CC_L   test-lt cond-br-sem)
(bicc-branch bgu  tgu  "gtu"    CC_GU  test-gtu cond-br-sem)
(bicc-branch bleu tleu "leu"    CC_LEU test-leu cond-br-sem)
(bicc-branch bcc  tcc  "geu"    CC_CC  test-geu cond-br-sem)
(bicc-branch bcs  tcs  "ltu"    CC_CS  test-ltu cond-br-sem)
(bicc-branch bpos tpos "pos"    CC_POS test-pos cond-br-sem)
(bicc-branch bneg tneg "neg"    CC_NEG test-neg cond-br-sem)
(bicc-branch bvc  tvc  "vc"     CC_VC  test-vc cond-br-sem)
(bicc-branch bvs  tvs  "vs"     CC_VS  test-vs cond-br-sem)

; Atomic load/stores.

(define-pmacro (atomic-op name comment attrs op3 do_fn)
  (begin
    (dnmi (.sym name "-reg") comment attrs
          (.str name " [$rs1],$rd")
          (emit (.sym name -reg+reg) rs1 (rs2 0) rd))
    (dnmi (.sym name "-reg+0") comment attrs
          (.str name " [$rs1],$rd")
          (emit (.sym name -reg+imm) rs1 (simm13 0) rd))
    (dni (.sym name "-reg+reg") comment attrs
         (.str name " [$rs1+$rs2],$rd")
         (+ OP_3 op3 rd rs1 (f-i 0) (f-res-asi 0) rs2)
         (c-call do_fn pc (regno rd) rs1 rs2 (const -1))
         ())
    (dni (.sym name "-reg+imm") comment attrs
         (.str name " [$rs1+$simm13],$rd")
         (+ OP_3 op3 rd rs1 (f-i 1) simm13)
         (c-call do_fn pc (regno rd) rs1 simm13 (const -1))
         ())
    (dnmi (.sym name "-reg/asi") comment attrs
          (.str name " [$rs1]$asi,$rd")
          (emit (.sym name "-reg+reg/asi") rs1 (rs2 0) asi rd))
    (dni (.sym name "-reg+reg/asi") comment attrs
         (.str name " [$rs1+$rs2]$asi,$rd")
         (+ OP_3 (.sym op3 A) rd rs1 (f-i 0) asi rs2)
         (c-call do_fn pc (regno rd) rs1 rs2 asi)
         ())
    )
)
(atomic-op ldstub "atomic load-store unsigned byte, v9 page 179" ()
         OP3_LDSTUB "@cpu@_do_ldstub")
(atomic-op swap "atomic swap reg with mem" (V9-DEPRECATED)
         OP3_SWAP "@cpu@_do_swap")

; TODO:
; - tagged add/sub
; - synthetic insns

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.