simplify target_is_pushed
[external/binutils.git] / cpu / or1korbis.cpu
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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")