|  | ; 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)))) | 
|  | ) | 
|  |  | 
|  | ; | 
|  | ; 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)") | 
|  | ) |