1; OpenRISC Basic Instruction Set 32-bit (ORBIS)  -*- Scheme -*-
2; Copyright 2000-2014 Free Software Foundation, Inc.
3; Contributed for OR32 by Johan Rydberg, jrydberg@opencores.org
4; Modified by Julius Baxter, juliusbaxter@gmail.com
5; Modified by Peter Gavin, pgavin@gmail.com
6;
7; This program is free software; you can redistribute it and/or modify
8; it under the terms of the GNU General Public License as published by
9; the Free Software Foundation; either version 3 of the License, or
10; (at your option) any later version.
11;
12; This program is distributed in the hope that it will be useful,
13; but WITHOUT ANY WARRANTY; without even the implied warranty of
14; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15; GNU General Public License for more details.
16;
17; You should have received a copy of the GNU General Public License
18; along with this program; if not, see <http://www.gnu.org/licenses/>
19
20; Instruction fields.
21
22; Hardware for immediate operands
23(dnh h-simm16      "16-bit signed immediate"   ((MACH ORBIS-MACHS)) (immediate (INT 16)) () () ())
24(dnh h-uimm16      "16-bit unsigned immediate" ()                   (immediate (UINT 16)) () () ())
25(dnh h-uimm6       "6-bit unsigned immediate"  ()                   (immediate (UINT 6)) () () ())
26
27; Hardware for the (internal) atomic registers
28(dsh h-atomic-reserve "atomic reserve flag" () (register BI))
29(dsh h-atomic-address "atomic reserve address" () (register SI))
30
31; Instruction classes.
32(dnf f-opcode      "insn opcode"               ((MACH ORBIS-MACHS)) 31 6)
33
34; Register fields.
35(dnf f-r1          "r1"                        ((MACH ORBIS-MACHS)) 25 5)
36(dnf f-r2          "r2"                        ((MACH ORBIS-MACHS)) 20 5)
37(dnf f-r3          "r3"                        ((MACH ORBIS-MACHS)) 15 5)
38
39; Sub fields
40(dnf f-op-25-2     "op-25-2"                   ((MACH ORBIS-MACHS)) 25 2) ;; nop
41(dnf f-op-25-5     "op-25-5"                   ((MACH ORBIS-MACHS)) 25 5) ;; sys, trap, *sync, sf*
42(dnf f-op-16-1     "op-16-1"                   ((MACH ORBIS-MACHS)) 16 1) ;; movhi,macrc
43(dnf f-op-7-4      "op-7-4"                    ((MACH ORBIS-MACHS)) 7 4)
44(dnf f-op-3-4      "op-3-4"                    ((MACH ORBIS-MACHS)) 3 4)
45(dnf f-op-9-2      "op-9-2"                    ((MACH ORBIS-MACHS)) 9 2) ;; alu ops upper opcode
46(dnf f-op-9-4      "op-9-4"                    ((MACH ORBIS-MACHS)) 9 4) ;;
47(dnf f-op-7-8      "op-7-8"                    ((MACH ORBIS-MACHS)) 7 8)
48(dnf f-op-7-2      "op-7-2"                    ((MACH ORBIS-MACHS)) 7 2) ;; alu lower upper opc,shroti
49
50; Reserved fields
51(dnf f-resv-25-26  "resv-25-26"                ((MACH ORBIS-MACHS) RESERVED) 25 26)
52(dnf f-resv-25-10  "resv-25-10"                ((MACH ORBIS-MACHS) RESERVED) 25 10)
53(dnf f-resv-25-5   "resv-25-5"                 ((MACH ORBIS-MACHS) RESERVED) 25 5)
54(dnf f-resv-23-8   "resv-23-8"                 ((MACH ORBIS-MACHS) RESERVED) 23 8)
55(dnf f-resv-20-21  "resv-20-21"                ((MACH ORBIS-MACHS) RESERVED) 20 21)
56(dnf f-resv-20-5   "resv-20-5"                 ((MACH ORBIS-MACHS) RESERVED) 20 5)
57(dnf f-resv-20-4   "resv-20-4"                 ((MACH ORBIS-MACHS) RESERVED) 20 4)
58(dnf f-resv-15-8   "resv-15-8"                 ((MACH ORBIS-MACHS) RESERVED) 15 8)
59(dnf f-resv-15-6   "resv-15-6"                 ((MACH ORBIS-MACHS) RESERVED) 15 6)
60(dnf f-resv-10-11  "resv-10-11"                ((MACH ORBIS-MACHS) RESERVED) 10 11)
61(dnf f-resv-10-7   "resv-10-7"                 ((MACH ORBIS-MACHS) RESERVED) 10 7)
62(dnf f-resv-10-3   "resv-10-3"                 ((MACH ORBIS-MACHS) RESERVED) 10 3)
63(dnf f-resv-10-1   "resv-10-1"                 ((MACH ORBIS-MACHS) RESERVED) 10 1)
64(dnf f-resv-7-4    "resv-7-4"                  ((MACH ORBIS-MACHS) RESERVED) 7 4)
65(dnf f-resv-5-2    "resv-5-2"                  ((MACH ORBIS-MACHS) RESERVED) 5 2)
66
67(dnf f-imm16-25-5  "imm16-25-5"                ((MACH ORBIS-MACHS)) 25  5)
68(dnf f-imm16-10-11 "imm16-10-11"               ((MACH ORBIS-MACHS)) 10 11)
69
70; PC relative, 26-bit (2 shifted to right)
71(df f-disp26
72    "disp26"
73    ((MACH ORBIS-MACHS) PCREL-ADDR)
74    25
75    26
76    INT
77    ((value pc) (sra SI (sub IAI value pc) (const 2)))
78    ((value pc) (add IAI (sll IAI value (const 2)) pc))
79    )
80
81; Immediates.
82(dnf f-uimm16    "uimm16"                      ((MACH ORBIS-MACHS))          15 16)
83(df  f-simm16    "simm16"                      ((MACH ORBIS-MACHS) SIGN-OPT) 15 16 INT #f #f)
84(dnf f-uimm6     "uimm6"                       ((MACH ORBIS-MACHS))          5  6) ;; shroti
85
86(define-multi-ifield
87  (name f-uimm16-split)
88  (comment "16-bit split unsigned immediate")
89  (attrs (MACH ORBIS-MACHS))
90  (mode UINT)
91  (subfields f-imm16-25-5 f-imm16-10-11)
92  (insert (sequence ()
93                    (set (ifield f-imm16-25-5)
94                         (and (srl (ifield f-uimm16-split)
95                                   (const 11))
96                              (const #x1f)))
97                    (set (ifield f-imm16-10-11)
98                         (and (ifield f-uimm16-split)
99                              (const #x7ff)))))
100  (extract 
101           (set (ifield f-uimm16-split)
102                (trunc UHI
103                       (or (sll (ifield f-imm16-25-5)
104                                (const 11))
105                           (ifield f-imm16-10-11)))))
106  )
107
108(define-multi-ifield
109  (name f-simm16-split)
110  (comment "16-bit split signed immediate")
111  (attrs (MACH ORBIS-MACHS) SIGN-OPT)
112  (mode INT)
113  (subfields f-imm16-25-5 f-imm16-10-11)
114  (insert (sequence ()
115                    (set (ifield f-imm16-25-5)
116                         (and (sra (ifield f-simm16-split)
117                                   (const 11))
118                              (const #x1f)))
119                    (set (ifield f-imm16-10-11)
120                         (and (ifield f-simm16-split)
121                              (const #x7ff)))))
122  (extract 
123           (set (ifield f-simm16-split)
124                (trunc HI
125                       (or (sll (ifield f-imm16-25-5)
126                                (const 11))
127                           (ifield f-imm16-10-11)))))
128  )
129
130; Enums.
131
132; insn-opcode: bits 31-26
133(define-normal-insn-enum 
134  insn-opcode "insn main opcode enums" ((MACH ORBIS-MACHS)) OPC_ f-opcode
135  (("J"            #x00)
136   ("JAL"          #x01)
137   ("BNF"          #x03)
138   ("BF"           #x04)
139   ("NOP"          #x05)
140   ("MOVHIMACRC"   #x06)
141   ("SYSTRAPSYNCS" #x08)
142   ("RFE"          #x09)
143   ("VECTOR"       #x0a)
144   ("JR"           #x11)
145   ("JALR"         #x12)
146   ("MACI"         #x13)
147   ("LWA"          #x1b)
148   ("CUST1"        #x1c)
149   ("CUST2"        #x1d)
150   ("CUST3"        #x1e)
151   ("CUST4"        #x1f)
152   ("LD"           #x20)
153   ("LWZ"          #x21)
154   ("LWS"          #x22)
155   ("LBZ"          #x23)
156   ("LBS"          #x24)
157   ("LHZ"          #x25)
158   ("LHS"          #x26)
159   ("ADDI"         #x27)
160   ("ADDIC"        #x28)
161   ("ANDI"         #x29)
162   ("ORI"          #x2a)
163   ("XORI"         #x2b)
164   ("MULI"         #x2c)
165   ("MFSPR"        #x2d)
166   ("SHROTI"       #x2e)
167   ("SFI"          #x2f)
168   ("MTSPR"        #x30)
169   ("MAC"          #x31)
170   ("FLOAT"        #x32)
171   ("SWA"          #x33)
172   ("SD"           #x34)
173   ("SW"           #x35)
174   ("SB"           #x36)
175   ("SH"           #x37)
176   ("ALU"          #x38)
177   ("SF"           #x39)
178   ("CUST5"        #x3c)
179   ("CUST6"        #x3d)
180   ("CUST7"        #x3e)
181   ("CUST8"        #x3f) 
182  )
183)
184
185(define-normal-insn-enum insn-opcode-systrapsyncs 
186  "systrapsync insn opcode enums" ((MACH ORBIS-MACHS)) 
187  OPC_SYSTRAPSYNCS_ f-op-25-5
188    (("SYSCALL" #x00 )
189     ("TRAP" #x08 )
190     ("MSYNC" #x10 )
191     ("PSYNC" #x14 )
192     ("CSYNC" #x18 )
193    )
194)
195
196(define-normal-insn-enum insn-opcode-movehimacrc
197  "movhi/macrc insn opcode enums" ((MACH ORBIS-MACHS))
198  OPC_MOVHIMACRC_ f-op-16-1
199  (("MOVHI" #x0)
200   ("MACRC" #x1)
201  )
202)
203
204(define-normal-insn-enum insn-opcode-mac
205  "multiply/accumulate insn opcode enums" ((MACH ORBIS-MACHS))
206  OPC_MAC_ f-op-3-4
207  (("MAC" #x1)
208   ("MSB" #x2)
209   )
210  )
211
212(define-normal-insn-enum insn-opcode-shorts 
213  "shift/rotate insn opcode enums" ((MACH ORBIS-MACHS))
214  OPC_SHROTS_ f-op-7-2
215    (("SLL" #x0 )
216     ("SRL" #x1 )
217     ("SRA" #x2 )
218     ("ROR" #x3 )
219    )
220)
221
222(define-normal-insn-enum insn-opcode-extbhs
223  "extend byte/half opcode enums" ((MACH ORBIS-MACHS))
224  OPC_EXTBHS_ f-op-9-4
225  (("EXTHS" #x0)
226   ("EXTBS" #x1)
227   ("EXTHZ" #x2)
228   ("EXTBZ" #x3)
229   )
230)
231
232(define-normal-insn-enum insn-opcode-extws
233  "extend word opcode enums" ((MACH ORBIS-MACHS))
234  OPC_EXTWS_ f-op-9-4
235  (("EXTWS" #x0)
236   ("EXTWZ" #x1)
237   )
238)
239
240(define-normal-insn-enum insn-opcode-alu-regreg 
241  "alu reg/reg insn opcode enums" ((MACH ORBIS-MACHS))
242  OPC_ALU_REGREG_ f-op-3-4
243  (("ADD"   #x0)
244   ("ADDC"  #x1)
245   ("SUB"   #x2)
246   ("AND"   #x3)
247   ("OR"    #x4)
248   ("XOR"   #x5)
249   ("MUL"   #x6)
250   ("SHROT" #x8)
251   ("DIV"   #x9)
252   ("DIVU"  #xA)
253   ("MULU"  #xB)
254   ("EXTBH" #xC)
255   ("EXTW"  #xD)
256   ("CMOV"  #xE)
257   ("FFL1"  #xF)
258   )
259)
260
261(define-normal-insn-enum insn-opcode-setflag
262  "setflag insn opcode enums" ((MACH ORBIS-MACHS))
263  OPC_SF_ f-op-25-5
264    (("EQ"  #x00)
265     ("NE"  #x01)
266     ("GTU" #x02)
267     ("GEU" #x03)
268     ("LTU" #x04)
269     ("LEU" #x05)
270     ("GTS" #x0A)
271     ("GES" #x0B)
272     ("LTS" #x0C)
273     ("LES" #x0D)
274    )
275)
276
277
278; Instruction operands.
279
280(dnop sys-sr            "supervision register"             ((MACH ORBIS-MACHS) SEM-ONLY) h-sys-sr            f-nil)
281(dnop sys-esr0          "exception supervision register 0" ((MACH ORBIS-MACHS) SEM-ONLY) h-sys-esr0          f-nil)
282(dnop sys-epcr0         "exception PC register 0"          ((MACH ORBIS-MACHS) SEM-ONLY) h-sys-epcr0         f-nil)
283
284(dnop sys-sr-lee        "SR little endian enable bit"      ((MACH ORBIS-MACHS) SEM-ONLY) h-sys-sr-lee        f-nil)
285(dnop sys-sr-f          "SR flag bit"                      ((MACH ORBIS-MACHS) SEM-ONLY) h-sys-sr-f          f-nil)
286(dnop sys-sr-cy         "SR carry bit"                     ((MACH ORBIS-MACHS) SEM-ONLY) h-sys-sr-cy         f-nil)
287(dnop sys-sr-ov         "SR overflow bit"                  ((MACH ORBIS-MACHS) SEM-ONLY) h-sys-sr-ov         f-nil)
288(dnop sys-sr-ove        "SR overflow exception enable bit" ((MACH ORBIS-MACHS) SEM-ONLY) h-sys-sr-ove        f-nil)
289(dnop sys-cpucfgr-ob64s "CPUCFGR ORBIS64 supported bit"    ((MACH ORBIS-MACHS) SEM-ONLY) h-sys-cpucfgr-ob64s f-nil)
290(dnop sys-cpucfgr-nd    "CPUCFGR no delay bit"             ((MACH ORBIS-MACHS) SEM-ONLY) h-sys-cpucfgr-nd    f-nil)
291(dnop sys-fpcsr-rm      "floating point round mode"        ((MACH ORBIS-MACHS) SEM-ONLY) h-sys-fpcsr-rm      f-nil)
292
293(dnop mac-machi         "MAC HI result register"           ((MACH ORBIS-MACHS) SEM-ONLY) h-mac-machi         f-nil)
294(dnop mac-maclo         "MAC LO result register"           ((MACH ORBIS-MACHS) SEM-ONLY) h-mac-maclo         f-nil)
295
296(dnop atomic-reserve    "atomic reserve flag"              ((MACH ORBIS-MACHS) SEM-ONLY) h-atomic-reserve    f-nil)
297(dnop atomic-address    "atomic address"                   ((MACH ORBIS-MACHS) SEM-ONLY) h-atomic-address    f-nil)
298
299(dnop uimm6             "uimm6"                            ((MACH ORBIS-MACHS))          h-uimm6             f-uimm6)
300
301(dnop rD                "destination register"             ((MACH ORBIS-MACHS))          h-gpr               f-r1)
302(dnop rA                "source register A"                ((MACH ORBIS-MACHS))          h-gpr               f-r2)
303(dnop rB                "source register B"                ((MACH ORBIS-MACHS))          h-gpr               f-r3)
304
305(define-operand
306  (name disp26)
307  (comment "pc-rel 26 bit")
308  (attrs (MACH ORBIS-MACHS))
309  (type h-iaddr)
310  (index f-disp26)
311  (handlers (parse "disp26"))
312  )
313
314(define-operand
315  (name simm16)
316  (comment "16-bit signed immediate")
317  (attrs (MACH ORBIS-MACHS) SIGN-OPT)
318  (type h-simm16)
319  (index f-simm16)
320  (handlers (parse "simm16"))
321  )
322
323(define-operand
324  (name uimm16)
325  (comment "16-bit unsigned immediate")
326  (attrs (MACH ORBIS-MACHS))
327  (type h-uimm16)
328  (index f-uimm16)
329  (handlers (parse "uimm16"))
330  )
331
332(define-operand
333  (name simm16-split)
334  (comment "split 16-bit signed immediate")
335  (attrs (MACH ORBIS-MACHS) SIGN-OPT)
336  (type h-simm16)
337  (index f-simm16-split)
338  (handlers (parse "simm16"))
339)
340
341(define-operand
342  (name uimm16-split)
343  (comment "split 16-bit unsigned immediate")
344  (attrs (MACH ORBIS-MACHS))
345  (type h-uimm16)
346  (index f-uimm16-split)
347  (handlers (parse "uimm16"))
348)
349
350; Instructions.
351
352; Branch releated instructions 
353
354(define-pmacro (cti-link-return)
355  (set IAI (reg h-gpr 9) (add pc (if sys-cpucfgr-nd 4 8)))
356  )
357(define-pmacro (cti-transfer-control condition target)
358  ;; this mess is necessary because we're
359  ;; skipping the delay slot, but it's
360  ;; actually the start of the next basic
361  ;; block
362  (sequence ()
363            (if condition
364                (delay 1 (set IAI pc target))
365                (if sys-cpucfgr-nd
366                    (delay 1 (set IAI pc (add pc 4))))
367                )
368            (if sys-cpucfgr-nd
369                (skip 1)
370                )
371            )
372  )
373
374(define-pmacro
375  (define-cti
376    cti-name
377    cti-comment
378    cti-attrs
379    cti-syntax
380    cti-format
381    cti-semantics)
382  (begin
383    (dni
384      cti-name
385      cti-comment
386      (.splice (MACH ORBIS-MACHS) DELAYED-CTI NOT-IN-DELAY-SLOT (.unsplice cti-attrs))
387      cti-syntax
388      cti-format
389      (cti-semantics)
390      ()
391      )
392    )
393  )
394
395(define-cti
396  l-j
397  "jump (pc-relative iaddr)"
398  (!COND-CTI UNCOND-CTI)
399  "l.j ${disp26}"
400  (+ OPC_J disp26)
401  (.pmacro ()
402           (cti-transfer-control 1 disp26)
403           )
404  )
405
406(define-cti
407  l-jal
408  "jump and link (pc-relative iaddr)"
409  (!COND-CTI UNCOND-CTI)
410  "l.jal ${disp26}"
411  (+ OPC_JAL disp26)
412  (.pmacro ()
413           (sequence ()
414                     (cti-link-return)
415                     (cti-transfer-control 1 disp26)
416                     )
417           )
418  )
419
420(define-cti
421  l-jr
422  "jump register (absolute iaddr)"
423  (!COND-CTI UNCOND-CTI)
424  "l.jr $rB"
425  (+ OPC_JR (f-resv-25-10 0) rB (f-resv-10-11 0))
426  (.pmacro ()
427           (cti-transfer-control 1 rB)
428           )
429  )
430
431(define-cti
432  l-jalr
433  "jump register and link (absolute iaddr)"
434  (!COND-CTI UNCOND-CTI)
435  "l.jalr $rB"
436  (+ OPC_JALR (f-resv-25-10 0) rB (f-resv-10-11 0) )
437  (.pmacro ()
438           (sequence ()
439                     (cti-link-return)
440                     (cti-transfer-control 1 rB)
441                     )
442           )
443  )
444
445(define-cti
446  l-bnf
447  "branch if condition bit not set (pc relative iaddr)"
448  (COND-CTI !UNCOND-CTI)
449  "l.bnf ${disp26}"
450  (+ OPC_BNF disp26)
451  (.pmacro ()
452           (cti-transfer-control (not sys-sr-f) disp26)
453           )
454  )
455
456(define-cti
457  l-bf
458  "branch if condition bit set (pc relative iaddr)"
459  (COND-CTI !UNCOND-CTI)
460  "l.bf ${disp26}"
461  (+ OPC_BF disp26)
462  (.pmacro ()
463           (cti-transfer-control sys-sr-f disp26)
464           )
465  )
466
467(dni l-trap "trap (exception)"
468     ((MACH ORBIS-MACHS) NOT-IN-DELAY-SLOT)
469     "l.trap ${uimm16}"
470     (+ OPC_SYSTRAPSYNCS OPC_SYSTRAPSYNCS_TRAP (f-resv-20-5 0) uimm16)
471     ; Do exception entry handling in C function, PC set based on SR state
472     (raise-exception EXCEPT-TRAP)
473     ()
474)
475
476
477(dni l-sys "syscall (exception)"
478     ; This function may not be in delay slot
479     ((MACH ORBIS-MACHS) NOT-IN-DELAY-SLOT)
480
481     "l.sys ${uimm16}"
482     (+ OPC_SYSTRAPSYNCS OPC_SYSTRAPSYNCS_SYSCALL (f-resv-20-5 0) uimm16)
483     ; Do exception entry handling in C function, PC set based on SR state
484     (raise-exception EXCEPT-SYSCALL)
485     ()
486)
487
488(dni l-msync "memory sync"
489     ((MACH ORBIS-MACHS))
490     "l.msync"
491     (+ OPC_SYSTRAPSYNCS OPC_SYSTRAPSYNCS_MSYNC (f-resv-20-21 0))
492     (nop)
493     ()
494)
495
496(dni l-psync "pipeline sync"
497     ((MACH ORBIS-MACHS))
498     "l.psync"
499     (+ OPC_SYSTRAPSYNCS OPC_SYSTRAPSYNCS_PSYNC (f-resv-20-21 0))
500     (nop)
501     ()
502)
503
504(dni l-csync "context sync"
505     ((MACH ORBIS-MACHS))
506     "l.csync"
507     (+ OPC_SYSTRAPSYNCS OPC_SYSTRAPSYNCS_CSYNC (f-resv-20-21 0))
508     (nop)
509     ()
510)
511
512(dni l-rfe "return from exception"
513     ; This function may not be in delay slot
514     ((MACH ORBIS-MACHS) NOT-IN-DELAY-SLOT FORCED-CTI)
515
516     "l.rfe"
517     (+ OPC_RFE (f-resv-25-26 0))
518     (c-call VOID "@cpu@_rfe")
519     ()
520)
521
522
523; Misc instructions
524
525; l.nop with immediate must be first so it handles all l.nops in sim
526(dni l-nop-imm "nop uimm16"
527     ((MACH ORBIS-MACHS))
528     "l.nop ${uimm16}"
529     (+ OPC_NOP (f-op-25-2 #x1) (f-resv-23-8 0) uimm16)
530     (c-call VOID "@cpu@_nop" (zext UWI uimm16))
531     ()
532     )
533
534(if (application-is? SIMULATOR)
535    (begin)
536    (begin
537      (dni l-nop "nop"
538           ((MACH ORBIS-MACHS))
539           "l.nop"
540           (+ OPC_NOP (f-op-25-2 #x1) (f-resv-23-8 0) uimm16)
541           (nop)
542           ()
543           )
544      )
545)
546
547(dni l-movhi "movhi reg/uimm16"
548     ((MACH ORBIS-MACHS))
549     "l.movhi $rD,$uimm16"
550     (+ OPC_MOVHIMACRC rD (f-resv-20-4 0) OPC_MOVHIMACRC_MOVHI uimm16)
551     (set UWI rD (sll UWI (zext UWI uimm16) (const 16)))
552     ()
553)
554
555(dni l-macrc "macrc reg"
556     ((MACH ORBIS-MACHS))
557     "l.macrc $rD"
558     (+ OPC_MOVHIMACRC rD (f-resv-20-4 0) OPC_MOVHIMACRC_MACRC (f-uimm16 0))
559     (sequence ()
560               (set UWI rD mac-maclo)
561               (set UWI mac-maclo 0)
562               (set UWI mac-machi 0)
563               )
564     ()
565     )
566
567
568; System releated instructions
569
570(dni l-mfspr "mfspr"
571     ((MACH ORBIS-MACHS))
572     "l.mfspr $rD,$rA,${uimm16}"
573     (+ OPC_MFSPR rD rA uimm16)
574     (set UWI rD (c-call UWI "@cpu@_mfspr" (or rA (zext UWI uimm16))))
575     ()
576)
577
578(dni l-mtspr "mtspr"
579     ((MACH ORBIS-MACHS))
580     "l.mtspr $rA,$rB,${uimm16-split}"
581     (+ OPC_MTSPR rA rB uimm16-split )
582     (c-call VOID "@cpu@_mtspr" (or rA (zext WI uimm16-split)) rB)
583     ()
584)
585
586
587; Load instructions
588(define-pmacro (load-store-addr base offset size)
589  (c-call AI "@cpu@_make_load_store_addr" base (ext SI offset) size))
590
591(dni l-lwz "l.lwz reg/simm16(reg)"
592     ((MACH ORBIS-MACHS))
593     "l.lwz $rD,${simm16}($rA)"
594     (+ OPC_LWZ rD rA simm16)
595     (set UWI rD (zext UWI (mem USI (load-store-addr rA simm16 4))))
596     ()
597)
598
599
600(dni l-lws "l.lws reg/simm16(reg)"
601     ((MACH ORBIS-MACHS))
602     "l.lws $rD,${simm16}($rA)"
603     (+ OPC_LWS rD rA simm16)
604     (set WI rD (ext WI (mem SI (load-store-addr rA simm16 4))))
605     ()
606)
607
608(dni l-lwa "l.lwa reg/simm16(reg)"
609     ((MACH ORBIS-MACHS))
610     "l.lwa $rD,${simm16}($rA)"
611     (+ OPC_LWA rD rA simm16)
612     (sequence ()
613               (set UWI rD (zext UWI (mem USI (load-store-addr rA simm16 4))))
614               (set atomic-reserve (const 1))
615               (set atomic-address (load-store-addr rA simm16 4))
616               )
617     ()
618)
619
620(dni l-lbz "l.lbz reg/simm16(reg)"
621     ((MACH ORBIS-MACHS))
622     "l.lbz $rD,${simm16}($rA)"
623     (+ OPC_LBZ rD rA simm16)
624     (set UWI rD (zext UWI (mem UQI (load-store-addr rA simm16 1))))
625     ()
626)
627
628(dni l-lbs "l.lbs reg/simm16(reg)"
629     ((MACH ORBIS-MACHS))
630     "l.lbs $rD,${simm16}($rA)"
631     (+ OPC_LBS rD rA simm16)
632     (set WI rD (ext WI (mem QI (load-store-addr rA simm16 1))))
633     ()
634)
635
636(dni l-lhz "l.lhz reg/simm16(reg)"
637     ((MACH ORBIS-MACHS))
638     "l.lhz $rD,${simm16}($rA)"
639     (+ OPC_LHZ rD simm16 rA)
640     (set UWI rD (zext UWI (mem UHI (load-store-addr rA simm16 2))))
641     ()
642)
643
644(dni l-lhs "l.lhs reg/simm16(reg)"
645     ((MACH ORBIS-MACHS))
646     "l.lhs $rD,${simm16}($rA)"
647     (+ OPC_LHS rD rA simm16)
648     (set WI rD (ext WI (mem HI (load-store-addr rA simm16 2))))
649     ()
650)
651
652
653; Store instructions
654
655(define-pmacro (store-insn mnemonic opc-op mode size)
656  (begin
657     (dni (.sym l- mnemonic)
658          (.str "l." mnemonic " simm16(reg)/reg")
659          ((MACH ORBIS-MACHS))
660          (.str "l." mnemonic " ${simm16-split}($rA),$rB")
661          (+ opc-op rA rB simm16-split)
662          (sequence ((SI addr))
663		    (set addr (load-store-addr rA simm16-split size))
664		    (set mode (mem mode addr) (trunc mode rB))
665		    (if (eq (and addr #xffffffc) atomic-address)
666			(set atomic-reserve (const 0))
667			)
668                    )
669          ()
670     )
671   )
672)
673
674(store-insn sw OPC_SW USI 4)
675(store-insn sb OPC_SB UQI 1)
676(store-insn sh OPC_SH UHI 2)
677
678(dni l-swa "l.swa simm16(reg)/reg"
679     ((MACH ORBIS-MACHS))
680     "l.swa ${simm16-split}($rA),$rB"
681     (+ OPC_SWA rA rB simm16)
682     (sequence ((SI addr) (BI flag))
683	       (set addr (load-store-addr rA simm16-split 4))
684	       (set sys-sr-f (and atomic-reserve (eq addr atomic-address)))
685	       (if sys-sr-f
686		   (set USI (mem USI addr) (trunc USI rB))
687		   )
688	       (set atomic-reserve (const 0))
689	       )
690     ()
691)
692
693
694; Shift and rotate instructions
695
696(define-pmacro (shift-insn mnemonic)
697  (begin
698     (dni (.sym l- mnemonic)
699          (.str "l." mnemonic " reg/reg/reg")
700          ((MACH ORBIS-MACHS))
701          (.str "l." mnemonic " $rD,$rA,$rB")
702          (+ OPC_ALU rD rA rB (f-resv-10-3 0) (.sym OPC_SHROTS_ (.upcase mnemonic)) (f-resv-5-2 0) 
703	     OPC_ALU_REGREG_SHROT )
704          (set UWI rD (mnemonic rA rB))
705          ()
706     )
707     (dni (.sym l- mnemonic "i")
708          (.str "l." mnemonic " reg/reg/uimm6")
709          ((MACH ORBIS-MACHS))
710          (.str "l." mnemonic "i $rD,$rA,${uimm6}")
711          (+ OPC_SHROTI rD rA (f-resv-15-8 0) (.sym OPC_SHROTS_ (.upcase mnemonic)) uimm6)
712          (set rD (mnemonic rA uimm6))
713          ()
714     )
715   )
716)
717
718(shift-insn sll)
719(shift-insn srl)
720(shift-insn sra)
721(shift-insn ror)
722
723
724; Arithmetic insns
725
726; ALU op macro
727(define-pmacro (alu-insn mnemonic)
728  (begin
729     (dni (.sym l- mnemonic)
730          (.str "l." mnemonic " reg/reg/reg")
731          ((MACH ORBIS-MACHS))
732          (.str "l." mnemonic " $rD,$rA,$rB")
733          (+ OPC_ALU rD rA rB (f-resv-10-7 0) (.sym OPC_ALU_REGREG_ (.upcase mnemonic)))
734          (set rD (mnemonic rA rB))
735          ()
736     )
737  )
738)
739
740(alu-insn and)
741(alu-insn or)
742(alu-insn xor)
743
744(define-pmacro (alu-carry-insn mnemonic)
745  (begin
746    (dni (.sym l- mnemonic)
747         (.str "l." mnemonic " reg/reg/reg")
748         ((MACH ORBIS-MACHS))
749         (.str "l." mnemonic " $rD,$rA,$rB")
750         (+ OPC_ALU rD rA rB (f-resv-10-7 #x00) (.sym OPC_ALU_REGREG_ (.upcase mnemonic)))
751         (sequence ()
752                   (sequence ()
753                             (set BI sys-sr-cy ((.sym mnemonic "c-cflag") WI rA rB 0))
754                             (set BI sys-sr-ov ((.sym mnemonic "c-oflag") WI rA rB 0))
755                             (set rD (mnemonic WI rA rB))
756                             )
757                   (if (andif sys-sr-ov sys-sr-ove)
758                       (raise-exception EXCEPT-RANGE))
759                   )
760         ()
761         )
762    )
763  )
764
765(alu-carry-insn add)
766(alu-carry-insn sub)
767
768(dni (l-addc) "l.addc reg/reg/reg"
769          ((MACH ORBIS-MACHS))
770          ("l.addc $rD,$rA,$rB")
771          (+ OPC_ALU rD rA rB (f-resv-10-7 #x00) OPC_ALU_REGREG_ADDC)
772          (sequence ()
773                    (sequence ((BI tmp-sys-sr-cy))
774                              (set BI tmp-sys-sr-cy sys-sr-cy)
775                              (set BI sys-sr-cy (addc-cflag WI rA rB tmp-sys-sr-cy))
776                              (set BI sys-sr-ov (addc-oflag WI rA rB tmp-sys-sr-cy))
777                              (set rD (addc WI rA rB tmp-sys-sr-cy))
778                              )
779                   (if (andif sys-sr-ov sys-sr-ove)
780                       (raise-exception EXCEPT-RANGE))
781                   )
782          ()
783)
784
785(dni (l-mul) "l.mul reg/reg/reg"
786          ((MACH ORBIS-MACHS))
787          ("l.mul $rD,$rA,$rB")
788          (+ OPC_ALU rD rA rB (f-resv-10-7 #x30) OPC_ALU_REGREG_MUL)
789          (sequence ()
790                    (sequence ()
791                              ; 2's complement overflow
792                              (set BI sys-sr-ov (mul-o2flag WI rA rB))
793                              ; 1's complement overflow
794                              (set BI sys-sr-cy (mul-o1flag WI rA rB))
795                              (set rD (mul WI rA rB))
796                              )
797                    (if (andif sys-sr-ov sys-sr-ove)
798                        (raise-exception EXCEPT-RANGE))
799                    )
800          ()
801)
802
803(dni (l-mulu) "l.mulu reg/reg/reg"
804          ((MACH ORBIS-MACHS))
805          ("l.mulu $rD,$rA,$rB")
806          (+ OPC_ALU rD rA rB (f-resv-10-7 #x30) OPC_ALU_REGREG_MULU)
807          (sequence ()
808                    (sequence ()
809                              ; 2's complement overflow
810                              (set BI sys-sr-ov 0)
811                              ; 1's complement overflow
812                              (set BI sys-sr-cy (mul-o1flag UWI rA rB))
813                              (set rD (mul UWI rA rB))
814                              )
815                    (if (andif sys-sr-ov sys-sr-ove)
816                        (raise-exception EXCEPT-RANGE))
817                    )
818          ()
819)
820
821(dni l-div "divide (signed)"
822          ((MACH ORBIS-MACHS))
823          "l.div $rD,$rA,$rB"
824          (+ OPC_ALU rD rA rB (f-resv-10-7 #x30) OPC_ALU_REGREG_DIV)
825          (sequence ()
826                    (if (ne rB 0)
827                        (sequence ()
828                                  (set BI sys-sr-cy 0)
829                                  (set WI rD (div WI rA rB))
830                                  )
831                        (set BI sys-sr-cy 1)
832                        )
833                    (set BI sys-sr-ov 0)
834                    (if (andif sys-sr-cy sys-sr-ove)
835                        (raise-exception EXCEPT-RANGE))
836                    )
837          ()
838)
839
840(dni l-divu "divide (unsigned)"
841          ((MACH ORBIS-MACHS))
842          "l.divu $rD,$rA,$rB"
843          (+ OPC_ALU rD rA rB (f-resv-10-7 #x30) OPC_ALU_REGREG_DIVU)
844          (sequence ()
845                    (if (ne rB 0)
846                        (sequence ()
847                                  (set BI sys-sr-cy 0)
848                                  (set rD (udiv UWI rA rB))
849                                  )
850                        (set BI sys-sr-cy 1)
851                        )
852                    (set BI sys-sr-ov 0)
853                    (if (andif sys-sr-cy sys-sr-ove)
854                        (raise-exception EXCEPT-RANGE))
855                    )
856          ()
857)
858
859(dni l-ff1 "find first '1'"
860          ((MACH ORBIS-MACHS))
861          "l.ff1 $rD,$rA"
862          (+ OPC_ALU rD rA rB (f-resv-10-7 #x00) OPC_ALU_REGREG_FFL1)
863          (set rD (c-call UWI "@cpu@_ff1" rA))
864          ()
865)
866
867(dni l-fl1 "find last '1'"
868          ((MACH ORBIS-MACHS))
869          "l.fl1 $rD,$rA"
870          (+ OPC_ALU rD rA rB (f-resv-10-7 #x10) OPC_ALU_REGREG_FFL1)
871          (set rD (c-call UWI "@cpu@_fl1" rA))
872          ()
873)
874
875
876(define-pmacro (alu-insn-simm  mnemonic)
877  (begin
878      (dni (.sym l- mnemonic "i")
879          (.str "l." mnemonic " reg/reg/simm16")
880          ((MACH ORBIS-MACHS))
881          (.str "l." mnemonic "i $rD,$rA,$simm16")
882          (+ (.sym OPC_ (.upcase mnemonic) "I") rD rA simm16)
883          (set rD (mnemonic rA (ext WI simm16)))
884          ()
885     )
886   )
887)
888
889(define-pmacro (alu-insn-uimm  mnemonic)
890  (begin
891      (dni (.sym l- mnemonic "i")
892          (.str "l." mnemonic " reg/reg/uimm16")
893          ((MACH ORBIS-MACHS))
894          (.str "l." mnemonic "i $rD,$rA,$uimm16")
895          (+ (.sym OPC_ (.upcase mnemonic) "I") rD rA uimm16)
896          (set rD (mnemonic rA (zext UWI uimm16)))
897          ()
898     )
899   )
900)
901
902(alu-insn-uimm and)
903(alu-insn-uimm or)
904(alu-insn-simm xor)
905
906(define-pmacro (alu-carry-insn-simm mnemonic)
907  (begin
908    (dni (.sym l- mnemonic "i")
909         (.str "l." mnemonic "i reg/reg/simm16")
910         ((MACH ORBIS-MACHS))
911         (.str "l." mnemonic "i $rD,$rA,$simm16")
912         (+ (.sym OPC_ (.upcase mnemonic) "I") rD rA simm16)
913         (sequence ()
914                   (sequence ()
915                             (set BI sys-sr-cy ((.sym mnemonic "c-cflag") WI rA (ext WI simm16) 0))
916                             (set BI sys-sr-ov ((.sym mnemonic "c-oflag") WI rA (ext WI simm16) 0))
917                             (set rD (mnemonic WI rA (ext WI simm16)))
918                             )
919                   (if (andif sys-sr-ov sys-sr-ove)
920                       (raise-exception EXCEPT-RANGE))
921                   )
922         ()
923         )
924    )
925  )
926
927(alu-carry-insn-simm add)
928
929(dni (l-addic)
930     ("l.addic reg/reg/simm16")
931     ((MACH ORBIS-MACHS))
932     ("l.addic $rD,$rA,$simm16")
933     (+ OPC_ADDIC rD rA simm16)
934     (sequence ()
935               (sequence ((BI tmp-sys-sr-cy))
936                         (set BI tmp-sys-sr-cy sys-sr-cy)
937                         (set BI sys-sr-cy (addc-cflag WI rA (ext WI simm16) tmp-sys-sr-cy))
938                         (set BI sys-sr-ov (addc-oflag WI rA (ext WI simm16) tmp-sys-sr-cy))
939                         (set WI rD (addc WI rA (ext WI simm16) tmp-sys-sr-cy))
940                         )
941               (if (andif sys-sr-ov sys-sr-ove)
942                   (raise-exception EXCEPT-RANGE))
943               )
944     ()
945)
946
947(dni (l-muli)
948     "l.muli reg/reg/simm16"
949     ((MACH ORBIS-MACHS))
950     ("l.muli $rD,$rA,$simm16")
951     (+ OPC_MULI rD rA simm16)
952     (sequence ()
953               (sequence ()
954                         ; 2's complement overflow
955                         (set sys-sr-ov (mul-o2flag WI rA (ext WI simm16)))
956                         ; 1's complement overflow
957                         (set sys-sr-cy (mul-o1flag UWI rA (ext UWI simm16)))
958                         (set rD (mul WI rA (ext WI simm16)))
959                         )
960               (if (andif sys-sr-ov sys-sr-ove)
961                   (raise-exception EXCEPT-RANGE))
962               )
963     ()
964     )
965
966(define-pmacro (extbh-insn mnemonic extop extmode truncmode)
967  (begin
968    (dni (.sym l- mnemonic)
969         (.str "l." mnemonic " reg/reg")
970         ((MACH ORBIS-MACHS))
971         (.str "l." mnemonic " $rD,$rA")
972         (+ OPC_ALU rD rA (f-resv-15-6 0) (.sym OPC_EXTBHS_ (.upcase mnemonic)) (f-resv-5-2 0) OPC_ALU_REGREG_EXTBH)
973         (set rD (extop extmode (trunc truncmode rA)))
974         ()
975         )
976    )
977  )
978
979(extbh-insn exths ext  WI  HI)
980(extbh-insn extbs ext  WI  QI)
981(extbh-insn exthz zext UWI UHI)
982(extbh-insn extbz zext UWI UQI)
983
984(define-pmacro (extw-insn mnemonic extop extmode truncmode)
985  (begin
986    (dni (.sym l- mnemonic)
987         (.str "l." mnemonic " reg/reg")
988         ((MACH ORBIS-MACHS))
989         (.str "l." mnemonic " $rD,$rA")
990         (+ OPC_ALU rD rA (f-resv-15-6 0) (.sym OPC_EXTWS_ (.upcase mnemonic)) (f-resv-5-2 0) OPC_ALU_REGREG_EXTW)
991         (set rD (extop extmode (trunc truncmode rA)))
992         ()
993         )
994    )
995  )
996
997(extw-insn extws ext  WI  SI)
998(extw-insn extwz zext USI USI)
999
1000(dni l-cmov
1001     "l.cmov reg/reg/reg"
1002     ((MACH ORBIS-MACHS))
1003     "l.cmov $rD,$rA,$rB"
1004     (+ OPC_ALU rD rA rB (f-resv-10-1 0) (f-op-9-2 0) (f-resv-7-4 0) OPC_ALU_REGREG_CMOV)
1005     (if sys-sr-f
1006         (set UWI rD rA)
1007         (set UWI rD rB)
1008         )
1009     ()
1010     )
1011
1012; Compare instructions
1013
1014; Ordering compare
1015(define-pmacro (sf-insn op)
1016  (begin
1017     (dni (.sym l- "sf" op "s")                                               ; l-sfgts
1018          (.str "l.sf" op "s reg/reg")                                        ; "l.sfgts reg/reg"
1019          ((MACH ORBIS-MACHS))
1020          (.str "l.sf" op "s $rA,$rB")                                        ; "l.sfgts $rA,$rB"
1021          (+ OPC_SF (.sym "OPC_SF_" (.upcase op) "S") rA rB (f-resv-10-11 0)) ; (+ OPC_SF OPC_SF_GTS rA rB (f-resv-10-11 0))
1022          (set sys-sr-f (op WI rA rB))                                        ; (set sys-sr-f (gt WI rA rB))
1023          ()
1024          )
1025     (dni (.sym l- "sf" op "si")                                              ; l-sfgtsi
1026          (.str "l.sf" op "si reg/simm16")                                    ; "l.sfgtsi reg/simm16"
1027          ((MACH ORBIS-MACHS))
1028          (.str "l.sf" op "si $rA,$simm16")                                   ; "l.sfgtsi $rA,$simm16"
1029          (+ OPC_SFI (.sym "OPC_SF_" (.upcase op) "S") rA simm16)             ; (+ OPC_SFI OPC_SF_GTS rA simm16)
1030          (set sys-sr-f (op WI rA (ext WI simm16)))                           ; (set sys-sr-f (gt WI rA (ext WI simm16)))
1031          ()
1032          )
1033     (dni (.sym l- "sf" op "u")                                               ; l-sfgtu
1034          (.str "l.sf" op "u reg/reg")                                        ; "l.sfgtu reg/reg"
1035          ((MACH ORBIS-MACHS))
1036          (.str "l.sf" op "u $rA,$rB")                                        ; "l.sfgtu $rA,$rB"
1037          (+ OPC_SF (.sym "OPC_SF_" (.upcase op) "U") rA rB (f-resv-10-11 0)) ; (+ OPC_SF OPC_SF_GTU rA rB (f-resv-10-11 0))
1038          (set sys-sr-f ((.sym op "u") WI rA rB))                             ; (set sys-sr-f (gtu WI rA rB))
1039          ()
1040          )
1041     ; immediate is sign extended even for unsigned compare
1042     (dni (.sym l- "sf" op "ui")                                              ; l-sfgtui
1043          (.str "l.sf" op "ui reg/simm16")                                    ; "l.sfgtui reg/uimm16"
1044          ((MACH ORBIS-MACHS))
1045          (.str "l.sf" op "ui $rA,$simm16")                                   ; "l.sfgtui $rA,$simm16"
1046          (+ OPC_SFI (.sym "OPC_SF_" (.upcase op) "U") rA simm16)             ; (+ OPC_SFI OPC_SF_GTU rA simm16)
1047          (set sys-sr-f ((.sym op "u") WI rA (ext WI simm16)))                ; (set sys-sr-f (gtu WI rA (ext WI simm16)))
1048          ()
1049          )
1050     )
1051  )
1052
1053(sf-insn gt)
1054(sf-insn ge)
1055(sf-insn lt)
1056(sf-insn le)
1057
1058; Equality compare
1059(define-pmacro (sf-insn-eq op)
1060  (begin
1061     (dni (.sym l- "sf" op)
1062          (.str "l." op " reg/reg")
1063          ((MACH ORBIS-MACHS))
1064          (.str "l.sf" op " $rA,$rB")
1065          (+ OPC_SF (.sym "OPC_SF_" (.upcase op)) rA rB (f-resv-10-11 0))
1066          (set sys-sr-f (op WI rA rB))
1067          ()
1068     )
1069     (dni (.sym l- "sf" op "i")
1070          (.str "l.sf" op "i reg/simm16")
1071          ((MACH ORBIS-MACHS))
1072          (.str "l.sf" op "i $rA,$simm16")
1073          (+ OPC_SFI (.sym "OPC_SF_" (.upcase op)) rA simm16)
1074          (set sys-sr-f (op WI rA (ext WI simm16)))
1075          ()
1076     )
1077   )
1078)
1079
1080(sf-insn-eq eq)
1081(sf-insn-eq ne)
1082
1083(dni l-mac
1084     "l.mac reg/reg"
1085     ((MACH ORBIS-MACHS))
1086     "l.mac $rA,$rB"
1087     (+  OPC_MAC (f-op-25-5 0) rA rB (f-resv-10-7 0) OPC_MAC_MAC)
1088     (sequence ((WI prod) (DI result))
1089               (set WI prod (mul WI rA rB))
1090               (set DI result (add (join DI SI mac-machi mac-maclo) (ext DI prod)))
1091               (set SI mac-machi (subword SI result 0))
1092               (set SI mac-maclo (subword SI result 1))
1093               )
1094     ()
1095     )
1096
1097(dni l-msb
1098     "l.msb reg/reg"
1099     ((MACH ORBIS-MACHS))
1100     "l.msb $rA,$rB"
1101     (+  OPC_MAC (f-op-25-5 0) rA rB (f-resv-10-7 0) OPC_MAC_MSB)
1102     (sequence ((WI prod) (DI result))
1103               (set WI prod (mul WI rA rB))
1104               (set DI result (sub (join DI SI mac-machi mac-maclo) (ext DI prod)))
1105               (set SI mac-machi (subword SI result 0))
1106               (set SI mac-maclo (subword SI result 1))
1107               )
1108     ()
1109     )
1110
1111(dni l-maci
1112     "l.maci reg/simm16"
1113     ((MACH ORBIS-MACHS))
1114     "l.maci $rA,${simm16}"
1115     (+ OPC_MACI (f-resv-25-5 0) rA simm16)
1116     (sequence ((WI prod) (DI result))
1117               (set WI prod (mul WI (ext WI simm16) rA))
1118               (set DI result (add (join DI SI mac-machi mac-maclo) (ext DI prod)))
1119               (set SI mac-machi (subword SI result 0))
1120               (set SI mac-maclo (subword SI result 1))
1121               )
1122     ()
1123     )
1124
1125(define-pmacro (cust-insn cust-num)
1126  (begin
1127    (dni (.sym l- "cust" cust-num)
1128         (.str "l.cust" cust-num)
1129         ((MACH ORBIS-MACHS))
1130         (.str "l.cust" cust-num)
1131         (+ (.sym OPC_CUST cust-num) (f-resv-25-26 0))
1132         (nop)
1133         ()
1134         )
1135    )
1136  )
1137
1138(cust-insn "1")
1139(cust-insn "2")
1140(cust-insn "3")
1141(cust-insn "4")
1142(cust-insn "5")
1143(cust-insn "6")
1144(cust-insn "7")
1145(cust-insn "8")
1146