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