mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-12-21 04:42:53 +08:00
6ce26ac7c3
This patch adds support for OpenRISC 64-bit FPU operations on 32-bit cores by using register pairs. The functionality has been added to OpenRISC architecture specification version 1.3 as per architecture proposal 14[0]. For supporting assembly of both 64-bit and 32-bit precision instructions we have defined CGEN_VALIDATE_INSN_SUPPORTED. This allows cgen to use 64-bit bit architecture assembly parsing on 64-bit toolchains and 32-bit architecture assembly parsing on 32-bit toolchains. Without this the assembler has issues parsing register pairs. This patch also contains a few fixes to the symantics for existing OpenRISC single and double precision FPU operations. [0] https://openrisc.io/proposals/orfpx64a32 cpu/ChangeLog: yyyy-mm-dd Andrey Bacherov <avbacherov@opencores.org> Stafford Horne <shorne@gmail.com> * or1k.cpu (ORFPX64A32-MACHS): New pmacro. (ORFPX-MACHS): Removed pmacro. * or1k.opc (or1k_cgen_insn_supported): New function. (CGEN_VALIDATE_INSN_SUPPORTED): Define macro. (parse_regpair, print_regpair): New functions. * or1kcommon.cpu (h-spr, spr-shift, spr-address, h-gpr): Reorder and add comments. (h-fdr): Update comment to indicate or64. (reg-pair-reg-lo, reg-pair-reg-hi): New pmacros for register pairs. (h-fd32r): New hardware for 64-bit fpu registers. (h-i64r): New hardware for 64-bit int registers. * or1korbis.cpu (f-resv-8-1): New field. * or1korfpx.cpu (rDSF, rASF, rBSF): Update attribute to ORFPX32-MACHS. (rDDF, rADF, rBDF): Update operand comment to indicate or64. (f-rdoff-10-1, f-raoff-9-1, f-rboff-8-1): New fields. (h-roff1): New hardware. (double-field-and-ops mnemonic): New pmacro to generate operations rDD32F, rAD32F, rBD32F, rDDI and rADI. (float-regreg-insn): Update single precision generator to MACH ORFPX32-MACHS. Add generator for or32 64-bit instructions. (float-setflag-insn): Update single precision generator to MACH ORFPX32-MACHS. Fix double instructions from single to double precision. Add generator for or32 64-bit instructions. (float-cust-insn cust-num): Update single precision generator to MACH ORFPX32-MACHS. Add generator for or32 64-bit instructions. (lf-rem-s, lf-itof-s, lf-ftoi-s, lf-madd-s): Update MACH to ORFPX32-MACHS. (lf-rem-d): Fix operation from mod to rem. (lf-rem-d32, lf-itof-d32, lf-ftoi-d32, lf-madd-d32): New instruction. (lf-itof-d): Fix operands from single to double. (lf-ftoi-d): Update operand mode from DI to WI.
441 lines
14 KiB
Scheme
441 lines
14 KiB
Scheme
; OpenRISC 1000 32-bit CPU hardware description. -*- Scheme -*-
|
|
; Copyright 2000-2019 Free Software Foundation, Inc.
|
|
; Contributed for OR32 by Johan Rydberg, jrydberg@opencores.org
|
|
; Modified by Julius Baxter, juliusbaxter@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/>
|
|
|
|
; Hardware pieces.
|
|
; These entries list the elements of the raw hardware.
|
|
; They're also used to provide tables and other elements of the assembly
|
|
; language.
|
|
|
|
(define-hardware
|
|
(name h-pc)
|
|
(comment "program counter")
|
|
(attrs PC (MACH ORBIS-MACHS))
|
|
(type pc UWI)
|
|
(get () (raw-reg h-pc))
|
|
(set (newval) (sequence ()
|
|
(set (reg h-sys-ppc) (raw-reg h-pc))
|
|
(set (raw-reg h-pc) newval)
|
|
))
|
|
)
|
|
|
|
(define-pmacro REG-INDICES
|
|
((r0 0)
|
|
(r1 1)
|
|
(r2 2)
|
|
(r3 3)
|
|
(r4 4)
|
|
(r5 5)
|
|
(r6 6)
|
|
(r7 7)
|
|
(r8 8)
|
|
(r9 9)
|
|
(r10 10)
|
|
(r11 11)
|
|
(r12 12)
|
|
(r13 13)
|
|
(r14 14)
|
|
(r15 15)
|
|
(r16 16)
|
|
(r17 17)
|
|
(r18 18)
|
|
(r19 19)
|
|
(r20 20)
|
|
(r21 21)
|
|
(r22 22)
|
|
(r23 23)
|
|
(r24 24)
|
|
(r25 25)
|
|
(r26 26)
|
|
(r27 27)
|
|
(r28 28)
|
|
(r29 29)
|
|
(r30 30)
|
|
(r31 31)
|
|
(lr 9)
|
|
(sp 1)
|
|
(fp 2))
|
|
)
|
|
|
|
;
|
|
; Hardware: [S]pecial [P]urpose [R]egisters
|
|
;
|
|
(define-hardware
|
|
(name h-spr) (comment "special purpose registers")
|
|
(attrs VIRTUAL (MACH ORBIS-MACHS))
|
|
(type register UWI (#x20000))
|
|
(get (index) (c-call UWI "@cpu@_h_spr_get_raw" index))
|
|
(set (index newval) (c-call VOID "@cpu@_h_spr_set_raw" index newval))
|
|
)
|
|
|
|
(define-pmacro spr-shift 11)
|
|
(define-pmacro (spr-address spr-group spr-index)
|
|
(or (sll UWI (enum UWI (.sym "SPR-GROUP-" spr-group)) spr-shift)
|
|
(enum UWI (.sym "SPR-INDEX-" spr-group "-" spr-index))))
|
|
|
|
;
|
|
; Hardware: [G]enepral [P]urpose [R]egisters
|
|
;
|
|
(define-hardware
|
|
(name h-gpr) (comment "general registers")
|
|
(attrs (MACH ORBIS-MACHS))
|
|
(type register UWI (32))
|
|
(indices keyword "" REG-INDICES)
|
|
(get (index) (reg UWI h-spr (add index (spr-address SYS GPR0))))
|
|
(set (index newval) (set UWI (reg UWI h-spr (add index (spr-address SYS GPR0))) newval))
|
|
)
|
|
|
|
;
|
|
; Hardware: virtual registerts for FPU (single precision)
|
|
; mapped to GPRs
|
|
;
|
|
(define-hardware
|
|
(name h-fsr)
|
|
(comment "floating point registers (single, virtual)")
|
|
(attrs VIRTUAL (MACH ORFPX32-MACHS))
|
|
(type register SF (32))
|
|
(indices keyword "" REG-INDICES)
|
|
(get (index) (subword SF (trunc SI (reg h-gpr index)) 0))
|
|
(set (index newval) (set UWI (reg h-gpr index) (zext UWI (subword SI newval 0))))
|
|
)
|
|
|
|
;
|
|
; Hardware: virtual registerts for FPU (double precision)
|
|
; mapped to GPRs
|
|
;
|
|
(define-hardware
|
|
(name h-fdr)
|
|
(comment "or64 floating point registers (double, virtual)")
|
|
(attrs VIRTUAL (MACH ORFPX64-MACHS))
|
|
(type register DF (32))
|
|
(indices keyword "" REG-INDICES)
|
|
(get (index) (subword DF (trunc DI (reg h-gpr index)) 0))
|
|
(set (index newval) (set UDI (reg h-gpr index) (zext UDI (subword DI newval 0))))
|
|
)
|
|
|
|
;
|
|
; Register pairs are offset by 2 for registers r16 and above. This is to
|
|
; be able to allow registers to be call saved in GCC across function calls.
|
|
;
|
|
(define-pmacro (reg-pair-reg-lo index)
|
|
(and index (const #x1f))
|
|
)
|
|
|
|
(define-pmacro (reg-pair-reg-hi index)
|
|
(add (and index (const #x1f))
|
|
(if (eq (sra index (const 5))
|
|
(const 1))
|
|
(const 2)
|
|
(const 1)
|
|
)
|
|
)
|
|
)
|
|
|
|
;
|
|
; Hardware: vrtual registers for double precision floating point
|
|
; operands on 32-bit machines
|
|
; mapped to GPRs
|
|
;
|
|
(define-hardware
|
|
(name h-fd32r)
|
|
(comment "or32 floating point registers (double, virtual)")
|
|
(attrs VIRTUAL (MACH ORFPX64A32-MACHS))
|
|
(type register DF (32))
|
|
(get (index) (join DF SI
|
|
(reg h-gpr (reg-pair-reg-lo index))
|
|
(reg h-gpr (reg-pair-reg-hi index))))
|
|
(set (index newval)
|
|
(sequence ()
|
|
(set (reg h-gpr (reg-pair-reg-lo index)) (subword SI newval 0))
|
|
(set (reg h-gpr (reg-pair-reg-hi index))
|
|
(subword SI newval 1))))
|
|
)
|
|
|
|
;
|
|
; Hardware: vrtual 64-bit integer registers for conversions
|
|
; float64 <-> int64 on 32-bit machines
|
|
; mapped to GPRs
|
|
;
|
|
(define-hardware
|
|
(name h-i64r)
|
|
(comment "or32 double word registers (int64, virtual)")
|
|
(attrs VIRTUAL (MACH ORFPX64A32-MACHS))
|
|
(type register DI (32))
|
|
(get (index) (join DI SI
|
|
(reg h-gpr (reg-pair-reg-lo index))
|
|
(reg h-gpr (reg-pair-reg-hi index))))
|
|
(set (index newval)
|
|
(sequence ()
|
|
(set (reg h-gpr (reg-pair-reg-lo index)) (subword SI newval 0))
|
|
(set (reg h-gpr (reg-pair-reg-hi index))
|
|
(subword SI newval 1))))
|
|
)
|
|
|
|
|
|
(define-normal-enum
|
|
except-number
|
|
"Exception numbers"
|
|
()
|
|
EXCEPT-
|
|
(("NONE" #x00)
|
|
("RESET" #x01)
|
|
("BUSERR" #x02)
|
|
("DPF" #x03)
|
|
("IPF" #x04)
|
|
("TICK" #x05)
|
|
("ALIGN" #x06)
|
|
("ILLEGAL" #x07)
|
|
("INT" #x08)
|
|
("DTLBMISS" #x09)
|
|
("ITLBMISS" #x0a)
|
|
("RANGE" #x0b)
|
|
("SYSCALL" #x0c)
|
|
("FPE" #x0d)
|
|
("TRAP" #x0e)
|
|
)
|
|
)
|
|
|
|
(define-pmacro (raise-exception exnum)
|
|
(c-call VOID "@cpu@_exception" pc exnum))
|
|
|
|
(define-normal-enum
|
|
spr-groups
|
|
"special purpose register groups"
|
|
()
|
|
SPR-GROUP-
|
|
(("SYS" #x0)
|
|
("DMMU" #x1)
|
|
("IMMU" #x2)
|
|
("DCACHE" #x3)
|
|
("ICACHE" #x4)
|
|
("MAC" #x5)
|
|
("DEBUG" #x6)
|
|
("PERF" #x7)
|
|
("POWER" #x8)
|
|
("PIC" #x9)
|
|
("TICK" #xa)
|
|
("FPU" #xb)
|
|
)
|
|
)
|
|
|
|
(define-pmacro (spr-reg-info)
|
|
(.splice
|
|
(SYS VR #x000 "version register")
|
|
(SYS UPR #x001 "unit present register")
|
|
(SYS CPUCFGR #x002 "cpu configuration register")
|
|
(SYS DMMUCFGR #x003 "Data MMU configuration register")
|
|
(SYS IMMUCFGR #x004 "Insn MMU configuration register")
|
|
(SYS DCCFGR #x005 "Data cache configuration register")
|
|
(SYS ICCFGR #x006 "Insn cache configuration register")
|
|
(SYS DCFGR #x007 "Debug configuration register")
|
|
(SYS PCCFGR #x008 "Performance counters configuration register")
|
|
(SYS NPC #x010 "Next program counter")
|
|
(SYS SR #x011 "Supervision Register")
|
|
(SYS PPC #x012 "Previous program counter")
|
|
(SYS FPCSR #x014 "Floating point control status register")
|
|
(.unsplice
|
|
(.map (.pmacro (n) (.splice SYS (.sym "EPCR" n) (.add n #x20) (.str "Exception PC register " n)))
|
|
(.iota #x10)))
|
|
(.unsplice
|
|
(.map (.pmacro (n) (.splice SYS (.sym "EEAR" n) (.add n #x30) (.str "Exception effective address register " n)))
|
|
(.iota #x10)))
|
|
(.unsplice
|
|
(.map (.pmacro (n) (.splice SYS (.sym "ESR" n) (.add n #x40) (.str "Exception supervision register " n)))
|
|
(.iota #x10)))
|
|
(.unsplice
|
|
(.map (.pmacro (n) (.splice SYS (.sym "GPR" n) (.add n #x400) (.str "General purpose register " n)))
|
|
(.iota #x200)))
|
|
|
|
(MAC MACLO #x001 "Multiply and accumulate result (low)")
|
|
(MAC MACHI #x002 "Multiply and accumulate result (high)")
|
|
(TICK TTMR #x000 "Tick timer mode register")
|
|
)
|
|
)
|
|
|
|
(define-normal-enum
|
|
spr-reg-indices
|
|
"special purpose register indices"
|
|
()
|
|
SPR-INDEX-
|
|
(.map (.pmacro (args)
|
|
(.apply (.pmacro (group index n comment)
|
|
((.sym group "-" index) n))
|
|
args)
|
|
)
|
|
(spr-reg-info)
|
|
)
|
|
)
|
|
|
|
(define-pmacro (define-h-spr-reg spr-group spr-index n spr-comment)
|
|
(define-hardware
|
|
(name (.sym "h-" (.downcase spr-group) "-" (.downcase spr-index)))
|
|
(comment spr-comment)
|
|
(attrs VIRTUAL (MACH ORBIS-MACHS))
|
|
(type register UWI)
|
|
(get () (reg UWI h-spr (spr-address spr-group spr-index)))
|
|
(set (newval) (set (reg UWI h-spr (spr-address spr-group spr-index)) newval))
|
|
)
|
|
)
|
|
(.splice begin (.unsplice (.map (.pmacro (args) (.apply define-h-spr-reg args)) (spr-reg-info))))
|
|
|
|
(define-pmacro (spr-field-info)
|
|
((SYS VR REV 5 0 "revision field")
|
|
(SYS VR CFG 23 16 "configuration template field")
|
|
(SYS VR VER 31 24 "version field")
|
|
(SYS UPR UP 0 0 "UPR present bit")
|
|
(SYS UPR DCP 1 1 "data cache present bit")
|
|
(SYS UPR ICP 2 2 "insn cache present bit")
|
|
(SYS UPR DMP 3 3 "data MMU present bit")
|
|
(SYS UPR MP 4 4 "MAC unit present bit")
|
|
(SYS UPR IMP 5 5 "insn MMU present bit")
|
|
(SYS UPR DUP 6 6 "debug unit present bit")
|
|
(SYS UPR PCUP 7 7 "performance counters unit present bit")
|
|
(SYS UPR PICP 8 8 "programmable interrupt controller present bit")
|
|
(SYS UPR PMP 9 9 "power management present bit")
|
|
(SYS UPR TTP 10 10 "tick timer present bit")
|
|
(SYS UPR CUP 31 24 "custom units present field")
|
|
(SYS CPUCFGR NSGR 3 0 "number of shadow GPR files field")
|
|
(SYS CPUCFGR CGF 4 4 "custom GPR file bit")
|
|
(SYS CPUCFGR OB32S 5 5 "ORBIS32 supported bit")
|
|
(SYS CPUCFGR OB64S 6 6 "ORBIS64 supported bit")
|
|
(SYS CPUCFGR OF32S 7 7 "ORFPX32 supported bit")
|
|
(SYS CPUCFGR OF64S 8 8 "ORFPX64 supported bit")
|
|
(SYS CPUCFGR OV64S 9 9 "ORVDX64 supported bit")
|
|
(SYS CPUCFGR ND 10 10 "no transfer delay bit")
|
|
(SYS SR SM 0 0 "supervisor mode bit")
|
|
(SYS SR TEE 1 1 "tick timer exception enabled bit")
|
|
(SYS SR IEE 2 2 "interrupt exception enabled bit")
|
|
(SYS SR DCE 3 3 "data cache enabled bit")
|
|
(SYS SR ICE 4 4 "insn cache enabled bit")
|
|
(SYS SR DME 5 5 "data MMU enabled bit")
|
|
(SYS SR IME 6 6 "insn MMU enabled bit")
|
|
(SYS SR LEE 7 7 "little endian enabled bit")
|
|
(SYS SR CE 8 8 "CID enable bit")
|
|
(SYS SR F 9 9 "flag bit")
|
|
(SYS SR CY 10 10 "carry bit")
|
|
(SYS SR OV 11 11 "overflow bit")
|
|
(SYS SR OVE 12 12 "overflow exception enabled bit")
|
|
(SYS SR DSX 13 13 "delay slot exception bit")
|
|
(SYS SR EPH 14 14 "exception prefix high bit")
|
|
(SYS SR FO 15 15 "fixed one bit")
|
|
(SYS SR SUMRA 16 16 "SPRs user mode read access bit")
|
|
(SYS SR CID 31 28 "context ID field")
|
|
(SYS FPCSR FPEE 0 0 "floating point exceptions enabled bit")
|
|
(SYS FPCSR RM 2 1 "floating point rounding mode field")
|
|
(SYS FPCSR OVF 3 3 "floating point overflow flag bit")
|
|
(SYS FPCSR UNF 4 4 "floating point underflow bit")
|
|
(SYS FPCSR SNF 5 5 "floating point SNAN flag bit")
|
|
(SYS FPCSR QNF 6 6 "floating point QNAN flag bit")
|
|
(SYS FPCSR ZF 7 7 "floating point zero flag bit")
|
|
(SYS FPCSR IXF 8 8 "floating point inexact flag bit")
|
|
(SYS FPCSR IVF 9 9 "floating point invalid flag bit")
|
|
(SYS FPCSR INF 10 10 "floating point infinity flag bit")
|
|
(SYS FPCSR DZF 11 11 "floating point divide by zero flag bit")
|
|
)
|
|
)
|
|
|
|
(define-normal-enum
|
|
spr-field-msbs
|
|
"SPR field msb positions"
|
|
()
|
|
SPR-FIELD-MSB-
|
|
(.map (.pmacro (args)
|
|
(.apply (.pmacro (group index field msb lsb comment)
|
|
((.sym group "-" index "-" field) msb)
|
|
)
|
|
args
|
|
)
|
|
)
|
|
(spr-field-info)
|
|
)
|
|
)
|
|
|
|
(define-normal-enum
|
|
spr-field-lsbs
|
|
"SPR field lsb positions"
|
|
()
|
|
SPR-FIELD-SIZE-
|
|
(.map (.pmacro (args)
|
|
(.apply (.pmacro (group index field msb lsb comment)
|
|
((.sym group "-" index "-" field) lsb)
|
|
)
|
|
args
|
|
)
|
|
)
|
|
(spr-field-info)
|
|
)
|
|
)
|
|
|
|
(define-normal-enum
|
|
spr-field-masks
|
|
"SPR field masks"
|
|
()
|
|
SPR-FIELD-MASK-
|
|
(.map (.pmacro (args)
|
|
(.apply (.pmacro (group index field msb lsb comment)
|
|
(.splice (.str group "-" index "-" field) (.sll (.inv (.sll (.inv 0) (.add (.sub msb lsb) 1))) lsb))
|
|
)
|
|
args
|
|
)
|
|
)
|
|
(spr-field-info)
|
|
)
|
|
)
|
|
|
|
(define-pmacro (define-h-spr-field spr-group spr-index spr-field spr-field-msb spr-field-lsb spr-field-comment)
|
|
(.let ((spr-field-name (.sym "h-" (.downcase spr-group) "-" (.downcase spr-index) "-" (.downcase spr-field)))
|
|
)
|
|
(begin
|
|
(define-hardware
|
|
(name spr-field-name)
|
|
(comment spr-field-comment)
|
|
(attrs VIRTUAL (MACH ORBIS-MACHS))
|
|
(type register UWI)
|
|
(get () (c-call UWI "@cpu@_h_spr_field_get_raw" (spr-address spr-group spr-index) spr-field-msb spr-field-lsb))
|
|
(set (value) (c-call VOID "@cpu@_h_spr_field_set_raw" (spr-address spr-group spr-index) spr-field-msb spr-field-lsb value))
|
|
)
|
|
)
|
|
)
|
|
)
|
|
(.splice begin (.unsplice (.map (.pmacro (args) (.apply define-h-spr-field args)) (spr-field-info))))
|
|
|
|
(define-attr
|
|
(type boolean)
|
|
(for insn)
|
|
(name DELAYED-CTI)
|
|
(comment "delayed control transfer instruction")
|
|
(values #f #t)
|
|
(default #f)
|
|
)
|
|
|
|
(define-attr
|
|
(for insn)
|
|
(type boolean)
|
|
(name NOT-IN-DELAY-SLOT)
|
|
(comment "instruction cannot be in delay slot")
|
|
(values #f #t)
|
|
(default #f)
|
|
)
|
|
|
|
(define-attr
|
|
(for insn)
|
|
(type boolean)
|
|
(name FORCED-CTI)
|
|
(comment "instruction may forcefully transfer control (e.g., rfe)")
|
|
)
|