]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - cpu/ip2k.cpu
ubsan: xstormy16: left shift of negative value
[thirdparty/binutils-gdb.git] / cpu / ip2k.cpu
CommitLineData
dc15e575
NC
1; Ubicom IP2K CPU description. -*- Scheme -*-
2; Copyright (C) 2002, 2009, 2011 Free Software Foundation, Inc.
3;
4; Contributed by Red Hat Inc;
5;
6; This file is part of the GNU Binutils.
7;
8; This program is free software; you can redistribute it and/or modify
9; it under the terms of the GNU General Public License as published by
10; the Free Software Foundation; either version 3 of the License, or
11; (at your option) any later version.
12;
13; This program is distributed in the hope that it will be useful,
14; but WITHOUT ANY WARRANTY; without even the implied warranty of
15; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16; GNU General Public License for more details.
17;
18; You should have received a copy of the GNU General Public License
19; along with this program; if not, write to the Free Software
20; Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21; MA 02110-1301, USA.
22
23(define-rtl-version 0 8)
24
25(include "simplify.inc")
26
27; define-arch must appear first
28
29(define-arch
30 (name ip2k) ; name of cpu family
31 (comment "Ubicom IP2000 family")
32 (default-alignment aligned)
33 (insn-lsb0? #t)
34 (machs ip2022 ip2022ext)
35 (isas ip2k)
36)
37
38; Attributes.
39
40(define-attr
41 (for insn)
42 (type boolean)
43 (name EXT-SKIP-INSN)
44 (comment "instruction is a PAGE, LOADL, LOADH or BREAKX instruction")
45)
46
47(define-attr
48 (for insn)
49 (type boolean)
50 (name SKIPA)
51 (comment "instruction is a SKIP instruction")
52)
53
54; Instruction set parameters.
55
56(define-isa
57 (name ip2k)
58 (comment "Ubicom IP2000 ISA")
59
60 (default-insn-word-bitsize 16)
61 (default-insn-bitsize 16)
62 (base-insn-bitsize 16)
63)
64\f
65; Cpu family definitions.
66
67
68(define-cpu
69 ; cpu names must be distinct from the architecture name and machine names.
70 (name ip2kbf)
71 (comment "Ubicom IP2000 Family")
72 (endian big)
73 (word-bitsize 16)
74)
75
76(define-mach
77 (name ip2022)
78 (comment "Ubicom IP2022")
79 (cpu ip2kbf)
80)
81
82(define-mach
83 (name ip2022ext)
84 (comment "Ubicom IP2022 extended")
85 (cpu ip2kbf)
86)
87
88\f
89; Model descriptions.
90
91(define-model
92 (name ip2k) (comment "VPE 2xxx") (attrs)
93 (mach ip2022ext)
94
95 (unit u-exec "Execution Unit" ()
96 1 1 ; issue done
97 () ; state
98 () ; inputs
99 () ; outputs
100 () ; profile action (default)
101 )
102)
103
104
105; FIXME: It might simplify things to separate the execute process from the
106; one that updates the PC.
107\f
108; Instruction fields.
109;
110; Attributes:
111; XXX: what VPE attrs
112; PCREL-ADDR: pc relative value (for reloc and disassembly purposes)
113; ABS-ADDR: absolute address (for reloc and disassembly purposes?)
114; RESERVED: bits are not used to decode insn, must be all 0
115; RELOC: there is a relocation associated with this field (experiment)
116
117
118(dnf f-imm8 "imm8" () 7 8)
119(dnf f-reg "reg" (ABS-ADDR) 8 9)
120(dnf f-addr16cjp "addr16cjp" (ABS-ADDR) 12 13)
121(dnf f-dir "dir" () 9 1)
122(dnf f-bitno "bit number" () 11 3)
123(dnf f-op3 "op3" () 15 3)
124(dnf f-op4 "op4" () 15 4)
125(dnf f-op4mid "op4mid" () 11 4)
126(dnf f-op6 "op6" () 15 6)
127(dnf f-op8 "op8" () 15 8)
128(dnf f-op6-10low "op6-10low" () 9 10)
129(dnf f-op6-7low "op6-7low" () 9 7)
130(dnf f-reti3 "reti3" () 2 3)
131(dnf f-skipb "sb/snb" (ABS-ADDR) 12 1)
132(dnf f-page3 "page3" () 2 3)
133;(define-ifield (name f-page3) (comment "page3") (attrs) (start 2) (length 3)
134; (encode (value pc) (srl WI value 13))
135; (decode (value pc) (sll WI value 13))
136;)
137; To fix the page/call asymmetry
138;(define-ifield (name f-page3) (comment "page3") (attrs) (start 2) (length 3)
139; (encode (value pc) (srl WI value 13))
140; (decode (value pc) (sll WI value 13))
141;)
142
143
144\f
145; Enums.
146
147; insn-op6: bits 15-10
148(define-normal-insn-enum insn-op6 "op6 enums" () OP6_ f-op6
149 (OTHER1 OTHER2 SUB DEC OR AND XOR ADD
150 TEST NOT INC DECSZ RR RL SWAP INCSZ
151 CSE POP SUBC DECSNZ MULU MULS INCSNZ ADDC
152 - - - - - - - -
153 - - - - - - - -
154 - - - - - - - -
155 - - - - - - - -
156 - - - - - - - -
157 )
158)
159
160; insn-dir: bit 9
161(define-normal-insn-enum insn-dir "dir enums" () DIR_ f-dir
162 ; This bit specifies the polarity of many two-operand instructions:
163 ; TO_W writes result to W regiser (eg. ADDC W,$fr)
164 ; NOTTO_W writes result in general register (eg. ADDC $fr,W)
165 (TO_W NOTTO_W)
166)
167
168
169; insn-op4: bits 15-12
170(define-normal-insn-enum insn-op4 "op4 enums" () OP4_ f-op4
171 (- - - - - - - LITERAL
172 CLRB SETB SNB SB - - - -
173 )
174)
175
176; insn-op4mid: bits 11-8
177; used for f-op4=LITERAL
178(define-normal-insn-enum insn-op4mid "op4mid enums" () OP4MID_ f-op4mid
179 (LOADH_L LOADL_L MULU_L MULS_L PUSH_L - CSNE_L CSE_L
180 RETW_L CMP_L SUB_L ADD_L MOV_L OR_L AND_L XOR_L)
181)
182
183; insn-op3: bits 15-13
184(define-normal-insn-enum insn-op3 "op3 enums" () OP3_ f-op3
185 (- - - - - - CALL JMP)
186)
187
188
189
190; Hardware pieces.
191
192; Bank-relative general purpose registers
193
194; (define-pmacro (build-reg-name n) (.splice (.str "$" n) n))
195
196(define-keyword
197 (name register-names)
198 (enum-prefix H-REGISTERS-)
199 (values
200 ; These are the "Special Purpose Registers" that are not reserved
201 ("ADDRSEL" #x2) ("ADDRX" #x3)
202 ("IPH" #x4) ("IPL" #x5) ("SPH" #x6) ("SPL" #x7)
203 ("PCH" #x8) ("PCL" #x9) ("WREG" #xA) ("STATUS" #xB)
204 ("DPH" #xC) ("DPL" #xD) ("SPDREG" #xE) ("MULH" #xF)
205 ("ADDRH" #x10) ("ADDRL" #x11) ("DATAH" #x12) ("DATAL" #x13)
206 ("INTVECH" #x14) ("INTVECL" #x15) ("INTSPD" #x16) ("INTF" #x17)
207 ("INTE" #x18) ("INTED" #x19) ("FCFG" #x1A) ("TCTRL" #x1B)
208 ("XCFG" #x1C) ("EMCFG" #x1D) ("IPCH" #x1E) ("IPCL" #x1F)
209 ("RAIN" #x20) ("RAOUT" #x21) ("RADIR" #x22) ("LFSRH" #x23)
210 ("RBIN" #x24) ("RBOUT" #x25) ("RBDIR" #x26) ("LFSRL" #x27)
211 ("RCIN" #x28) ("RCOUT" #x29) ("RCDIR" #x2A) ("LFSRA" #x2B)
212 ("RDIN" #x2C) ("RDOUT" #x2D) ("RDDIR" #x2E)
213 ("REIN" #x30) ("REOUT" #x31) ("REDIR" #x32)
214 ("RFIN" #x34) ("RFOUT" #x35) ("RFDIR" #x36)
215 ("RGOUT" #x39) ("RGDIR" #x3A)
216 ("RTTMR" #x40) ("RTCFG" #x41) ("T0TMR" #x42) ("T0CFG" #x43)
217 ("T1CNTH" #x44) ("T1CNTL" #x45) ("T1CAP1H" #x46) ("T1CAP1L" #x47)
218 ("T1CAP2H" #x48) ("T1CMP2H" #x48) ("T1CAP2L" #x49) ("T1CMP2L" #x49) ; note aliases
219 ("T1CMP1H" #x4A) ("T1CMP1L" #x4B)
220 ("T1CFG1H" #x4C) ("T1CFG1L" #x4D) ("T1CFG2H" #x4E) ("T1CFG2L" #x4F)
221 ("ADCH" #x50) ("ADCL" #x51) ("ADCCFG" #x52) ("ADCTMR" #x53)
222 ("T2CNTH" #x54) ("T2CNTL" #x55) ("T2CAP1H" #x56) ("T2CAP1L" #x57)
223 ("T2CAP2H" #x58) ("T2CMP2H" #x58) ("T2CAP2L" #x59) ("T2CMP2L" #x59) ; note aliases
224 ("T2CMP1H" #x5A) ("T2CMP1L" #x5B)
225 ("T2CFG1H" #x5C) ("T2CFG1L" #x5D) ("T2CFG2H" #x5E) ("T2CFG2L" #x5F)
226 ("S1TMRH" #x60) ("S1TMRL" #x61) ("S1TBUFH" #x62) ("S1TBUFL" #x63)
227 ("S1TCFG" #x64) ("S1RCNT" #x65) ("S1RBUFH" #x66) ("S1RBUFL" #x67)
228 ("S1RCFG" #x68) ("S1RSYNC" #x69) ("S1INTF" #x6A) ("S1INTE" #x6B)
229 ("S1MODE" #x6C) ("S1SMASK" #x6D) ("PSPCFG" #x6E) ("CMPCFG" #x6F)
230 ("S2TMRH" #x70) ("S2TMRL" #x71) ("S2TBUFH" #x72) ("S2TBUFL" #x73)
231 ("S2TCFG" #x74) ("S2RCNT" #x75) ("S2RBUFH" #x76) ("S2RBUFL" #x77)
232 ("S2RCFG" #x78) ("S2RSYNC" #x79) ("S2INTF" #x7A) ("S2INTE" #x7B)
233 ("S2MODE" #x7C) ("S2SMASK" #x7D) ("CALLH" #x7E) ("CALLL" #x7F))
234 )
235
236(define-hardware
237 (name h-spr)
238 (comment "special-purpose registers")
239 (type register QI (128))
240 (get (index) (c-call QI "get_spr" index ))
241 (set (index newval) (c-call VOID "set_spr" index newval ))
242)
243
244
245;;(define-hardware
246;; (name h-gpr-global)
247;; (comment "gpr registers - global")
248;; (type register QI (128))
249;;)
250
251; The general register
252
253(define-hardware
254 (name h-registers)
255 (comment "all addressable registers")
256 (attrs VIRTUAL)
257 (type register QI (512))
258 (get (index) (c-call QI "get_h_registers" index ))
259 (set (index newval) (c-call VOID "set_h_registers" index newval ))
260)
261
262; The hardware stack.
263; Use {push,pop}_pc_stack c-calls to operate on this hardware element.
264
265(define-hardware
266 (name h-stack)
267 (comment "hardware stack")
268 (type register UHI (16))
269)
270
271(dsh h-pabits "page bits" () (register QI))
272(dsh h-zbit "zero bit" () (register BI))
273(dsh h-cbit "carry bit" () (register BI))
274(dsh h-dcbit "digit-carry bit" () (register BI))
275(dnh h-pc "program counter" (PC PROFILE) (pc) () () ())
276
277
278; Operands
279
280(define-operand (name addr16cjp) (comment "13-bit address") (attrs)
281 (type h-uint) (index f-addr16cjp) (handlers (parse "addr16_cjp") (print "dollarhex_cj"))) ; overload lit8 printer
282(define-operand (name fr) (comment "register") (attrs)
283 (type h-registers) (index f-reg) (handlers (parse "fr") (print "fr")))
284(define-operand (name lit8) (comment "8-bit signed literal") (attrs)
285 (type h-sint) (index f-imm8) (handlers (parse "lit8") (print "dollarhex8")))
286(define-operand (name bitno) (comment "bit number") (attrs)
287 (type h-uint) (index f-bitno) (handlers (parse "bit3")(print "decimal")))
288(define-operand (name addr16p) (comment "page number") (attrs)
289 (type h-uint) (index f-page3) (handlers (parse "addr16_cjp") (print "dollarhex_p")))
290(define-operand (name addr16h) (comment "high 8 bits of address") (attrs)
291 (type h-uint) (index f-imm8) (handlers (parse "addr16") (print "dollarhex_addr16h")))
292(define-operand (name addr16l) (comment "low 8 bits of address") (attrs)
293 (type h-uint) (index f-imm8) (handlers (parse "addr16") (print "dollarhex_addr16l")))
294(define-operand (name reti3) (comment "reti flags") (attrs)
295 (type h-uint) (index f-reti3) (handlers (print "dollarhex")))
296(dnop pabits "page bits" () h-pabits f-nil)
297(dnop zbit "zero bit" () h-zbit f-nil)
298(dnop cbit "carry bit" () h-cbit f-nil)
299(dnop dcbit "digit carry bit" () h-dcbit f-nil)
300;;(dnop bank "bank register" () h-bank-no f-nil)
301
302(define-pmacro w (reg h-spr #x0A))
303(define-pmacro mulh (reg h-spr #x0F))
304(define-pmacro dph (reg h-spr #x0C))
305(define-pmacro dpl (reg h-spr #x0D))
306(define-pmacro sph (reg h-spr #x06))
307(define-pmacro spl (reg h-spr #x07))
308(define-pmacro iph (reg h-spr #x04))
309(define-pmacro ipl (reg h-spr #x05))
310(define-pmacro addrh (reg h-spr #x10))
311(define-pmacro addrl (reg h-spr #x11))
312
313
314
315; Pseudo-RTL for DC flag calculations
316; "DC" = "digit carry", ie carry between nibbles
317(define-pmacro (add-dcflag a b c)
318 (add-cflag (sll QI a 4) (sll QI b 4) c)
319)
320
321(define-pmacro (sub-dcflag a b c)
322 (sub-cflag (sll QI a 4) (sll QI b 4) c)
323)
324
325; Check to see if an fr is one of IPL, SPL, DPL, ADDRL, PCL.
326(define-pmacro (LregCheck isLreg fr9bit)
327 (sequence()
328 (set isLreg #x0) ;; Assume it's not an Lreg
329 (if (or (or (eq fr9bit #x5) (eq fr9bit #x7))
330 (or (eq fr9bit #x9)
331 (or (eq fr9bit #xd) (eq fr9bit #x11))))
332 (set isLreg #x1)
333 )
334 )
335)
336
337
338; Instructions, in order of the "Instruction Set Map" table on
339; pp 19-20 of IP2022 spec V1.09
340
341(dni jmp "Jump"
342 ()
343 "jmp $addr16cjp"
344 (+ OP3_JMP addr16cjp)
345 (set pc (or (sll pabits 13) addr16cjp))
346 ()
347)
348
349; note that in call, we push pc instead of pc + 1 because the ip2k increments
350; the pc prior to execution of the instruction
351(dni call "Call"
352 ()
353 "call $addr16cjp"
354 (+ OP3_CALL addr16cjp)
355 (sequence ()
356 (c-call "push_pc_stack" pc)
357 (set pc (or (sll pabits 13) addr16cjp)))
358 ()
359)
360
361(dni sb "Skip if bit set"
362 ()
363 "sb $fr,$bitno"
364 (+ OP4_SB bitno fr)
365 (if (and fr (sll 1 bitno))
366 (skip 1))
367 ()
368)
369
370(dni snb "Skip if bit clear"
371 ()
372 "snb $fr,$bitno"
373 (+ OP4_SNB bitno fr)
374 (if (not (and fr (sll 1 bitno)))
375 (skip 1))
376 ()
377)
378
379(dni setb "Set bit"
380 ()
381 "setb $fr,$bitno"
382 (+ OP4_SETB bitno fr)
383 (set fr (or fr (sll 1 bitno)))
384 ()
385)
386
387(dni clrb "Clear bit"
388 ()
389 "clrb $fr,$bitno"
390 (+ OP4_CLRB bitno fr)
391 (set fr (and fr (inv (sll 1 bitno))))
392 ()
393)
394
395(dni xorw_l "XOR W,literal"
396 ()
397 "xor W,#$lit8"
398 (+ OP4_LITERAL OP4MID_XOR_L lit8)
399 (sequence ()
400 (set w (xor w lit8))
401 (set zbit (zflag w)))
402 ()
403)
404
405(dni andw_l "AND W,literal"
406 ()
407 "and W,#$lit8"
408 (+ OP4_LITERAL OP4MID_AND_L lit8)
409 (sequence ()
410 (set w (and w lit8))
411 (set zbit (zflag w)))
412 ()
413)
414
415(dni orw_l "OR W,literal"
416 ()
417 "or W,#$lit8"
418 (+ OP4_LITERAL OP4MID_OR_L lit8)
419 (sequence ()
420 (set w (or w lit8))
421 (set zbit (zflag w)))
422 ()
423)
424
425(dni addw_l "ADD W,literal"
426 ()
427 "add W,#$lit8"
428 (+ OP4_LITERAL OP4MID_ADD_L lit8)
429 (sequence ()
430 (set cbit (add-cflag w lit8 0))
431 (set dcbit (add-dcflag w lit8 0))
432 (set w (add w lit8))
433 (set zbit (zflag w)))
434 ()
435)
436
437(dni subw_l "SUB W,literal"
438 ()
439 "sub W,#$lit8"
440 (+ OP4_LITERAL OP4MID_SUB_L lit8)
441 (sequence ()
442 (set cbit (not (sub-cflag lit8 w 0)))
443 (set dcbit (not (sub-dcflag lit8 w 0)))
444 (set zbit (zflag (sub w lit8)))
445 (set w (sub lit8 w)))
446 ()
447)
448
449(dni cmpw_l "CMP W,literal"
450 ()
451 "cmp W,#$lit8"
452 (+ OP4_LITERAL OP4MID_CMP_L lit8)
453 (sequence ()
454 (set cbit (not (sub-cflag lit8 w 0)))
455 (set dcbit (not (sub-dcflag lit8 w 0)))
456 (set zbit (zflag (sub w lit8))))
457 ()
458)
459
460(dni retw_l "RETW literal"
461 ()
462 "retw #$lit8"
463 (+ OP4_LITERAL OP4MID_RETW_L lit8)
464 (sequence ((USI new_pc))
465 (set w lit8)
466 (set new_pc (c-call UHI "pop_pc_stack"))
467 (set pabits (srl new_pc 13))
468 (set pc new_pc))
469 ()
470)
471
472(dni csew_l "CSE W,literal"
473 ()
474 "cse W,#$lit8"
475 (+ OP4_LITERAL OP4MID_CSE_L lit8)
476 (if (eq w lit8)
477 (skip 1))
478 ()
479)
480
481(dni csnew_l "CSNE W,literal"
482 ()
483 "csne W,#$lit8"
484 (+ OP4_LITERAL OP4MID_CSNE_L lit8)
485 (if (not (eq w lit8))
486 (skip 1))
487 ()
488)
489
490(dni push_l "Push #lit8"
491 ()
492 "push #$lit8"
493 (+ OP4_LITERAL OP4MID_PUSH_L lit8)
494 (sequence ()
495 (c-call "push" lit8)
496 (c-call VOID "adjuststackptr" (const -1))
497
498 )
499 ()
500)
501
502(dni mulsw_l "Multiply W,literal (signed)"
503 ()
504 "muls W,#$lit8"
505 (+ OP4_LITERAL OP4MID_MULS_L lit8)
506 (sequence ((SI tmp))
507 (set tmp (mul (ext SI w) (ext SI (and UQI #xff lit8))))
508 (set w (and tmp #xFF))
509 (set mulh (srl tmp 8)))
510 ()
511)
512
513(dni muluw_l "Multiply W,literal (unsigned)"
514 ()
515 "mulu W,#$lit8"
516 (+ OP4_LITERAL OP4MID_MULU_L lit8)
517 (sequence ((USI tmp))
518 (set tmp (and #xFFFF (mul (zext USI w) (zext USI lit8))))
519 (set w (and tmp #xFF))
520 (set mulh (srl tmp 8)))
521 ()
522)
523
524(dni loadl_l "LoadL literal"
525 (EXT-SKIP-INSN)
526 "loadl #$lit8"
527 (+ OP4_LITERAL OP4MID_LOADL_L lit8)
528 (set dpl (and lit8 #x00FF))
529 ()
530)
531
532(dni loadh_l "LoadH literal"
533 (EXT-SKIP-INSN)
534 "loadh #$lit8"
535 (+ OP4_LITERAL OP4MID_LOADH_L lit8)
536 (set dph (and lit8 #x00FF))
537 ()
538)
539
540(dni loadl_a "LoadL addr16l"
541 (EXT-SKIP-INSN)
542 "loadl $addr16l"
543 (+ OP4_LITERAL OP4MID_LOADL_L addr16l)
544 (set dpl (and addr16l #x00FF))
545 ()
546)
547
548(dni loadh_a "LoadH addr16h"
549 (EXT-SKIP-INSN)
550 "loadh $addr16h"
551 (+ OP4_LITERAL OP4MID_LOADH_L addr16h)
552 (set dph (and addr16l #x0FF00))
553 ()
554)
555
556;; THIS NO LONGER EXISTS -> Now LOADL
557;;(dni bank_l "Bank literal"
558;; ()
559;; "bank #$lit8"
560;; (+ OP4_LITERAL OP4MID_BANK_L lit8)
561;; (set bank lit8)
562;; ()
563;;)
564
565(dni addcfr_w "Add w/carry fr,W"
566 ()
567 "addc $fr,W"
568 (+ OP6_ADDC DIR_NOTTO_W fr)
569 (sequence ((QI result) (BI newcbit) (QI isLreg) (HI 16bval))
570 (set newcbit (add-cflag w fr cbit))
571 (set dcbit (add-dcflag w fr cbit))
572 ;; If fr is an Lreg, then we have to do 16-bit arithmetic.
573 ;; We can take advantage of the fact that by a lucky
574 ;; coincidence, the address of register xxxH is always
575 ;; one lower than the address of register xxxL.
576 (LregCheck isLreg (ifield f-reg))
577 (if (eq isLreg #x1)
578 (sequence()
579 (set 16bval (reg h-spr (sub (ifield f-reg) 1)))
580 (set 16bval (sll 16bval 8))
581 (set 16bval (or 16bval (and (reg h-spr (ifield f-reg)) #xFF)))
582 (set 16bval (addc HI 16bval w cbit))
583 (set (reg h-spr (ifield f-reg)) (and 16bval #xFF))
584 (set (reg h-spr (sub (ifield f-reg) 1))
585 (and (srl 16bval 8) #xFF))
586 (set result (reg h-spr (ifield f-reg)))
587 )
588 (set result (addc w fr cbit)) ;; else part
589 )
590
591 (set zbit (zflag result))
592 (set cbit newcbit)
593 (set fr result))
594 ()
595)
596
597(dni addcw_fr "Add w/carry W,fr"
598 ()
599 "addc W,$fr"
600 (+ OP6_ADDC DIR_TO_W fr)
601 (sequence ((QI result) (BI newcbit))
602 (set newcbit (add-cflag w fr cbit))
603 (set dcbit (add-dcflag w fr cbit))
604 (set result (addc w fr cbit))
605 (set zbit (zflag result))
606 (set cbit newcbit)
607 (set w result))
608 ()
609)
610
611
612(dni incsnz_fr "Skip if fr++ not zero"
613 ()
614 "incsnz $fr"
615 (+ OP6_INCSNZ DIR_NOTTO_W fr)
616 (sequence ((QI isLreg) (HI 16bval))
617 (LregCheck isLreg (ifield f-reg))
618 ;; If fr is an Lreg, then we have to do 16-bit arithmetic.
619 ;; We can take advantage of the fact that by a lucky
620 ;; coincidence, the address of register xxxH is always
621 ;; one lower than the address of register xxxL.
622 (if (eq isLreg #x1)
623 (sequence()
624 ; Create the 16 bit value
625 (set 16bval (reg h-spr (sub (ifield f-reg) 1)))
626 (set 16bval (sll 16bval 8))
627 (set 16bval (or 16bval (and (reg h-spr (ifield f-reg)) #xFF)))
628 ; Do 16 bit arithmetic.
629 (set 16bval (add HI 16bval 1))
630 ; Separate the 16 bit values into the H and L regs
631 (set (reg h-spr (ifield f-reg)) (and 16bval #xFF))
632 (set (reg h-spr (sub (ifield f-reg) 1))
633 (and (srl 16bval 8) #xFF))
634 (set fr (reg h-spr (ifield f-reg)))
635 )
636 (set fr (add fr 1)) ; Do 8 bit arithmetic.
637 )
638 (if (not (zflag fr))
639 (skip 1)))
640 ()
641)
642
643(dni incsnzw_fr "Skip if W=fr+1 not zero"
644 ()
645 "incsnz W,$fr"
646 (+ OP6_INCSNZ DIR_TO_W fr)
647 (sequence ()
648 (set w (add fr 1))
649 (if (not (zflag w))
650 (skip 1)))
651 ()
652)
653
654(dni mulsw_fr "Multiply W,fr (signed)"
655 ()
656 "muls W,$fr"
657 (+ OP6_MULS DIR_TO_W fr)
658 (sequence ((SI tmp))
659 (set tmp (mul (ext SI w) (ext SI fr)))
660 (set w (and tmp #xFF))
661 (set mulh (srl tmp 8)))
662 ()
663)
664
665(dni muluw_fr "Multiply W,fr (unsigned)"
666 ()
667 "mulu W,$fr"
668 (+ OP6_MULU DIR_TO_W fr)
669 (sequence ((USI tmp))
670 (set tmp (and #xFFFF (mul (zext USI w) (zext USI fr))))
671 (set w (and tmp #xFF))
672 (set mulh (srl tmp 8)))
673 ()
674)
675
676(dni decsnz_fr "Skip if fr-- not zero"
677 ()
678 "decsnz $fr"
679 (+ OP6_DECSNZ DIR_NOTTO_W fr)
680 (sequence ((QI isLreg) (HI 16bval))
681 (LregCheck isLreg (ifield f-reg))
682 ;; If fr is an Lreg, then we have to do 16-bit arithmetic.
683 ;; We can take advantage of the fact that by a lucky
684 ;; coincidence, the address of register xxxH is always
685 ;; one lower than the address of register xxxL.
686 (if (eq isLreg #x1)
687 (sequence()
688 ; Create the 16 bit value
689 (set 16bval (reg h-spr (sub (ifield f-reg) 1)))
690 (set 16bval (sll 16bval 8))
691 (set 16bval (or 16bval (and (reg h-spr (ifield f-reg)) #xFF)))
692 ; New 16 bit instruction
693 (set 16bval (sub HI 16bval 1))
694 ; Separate the 16 bit values into the H and L regs
695 (set (reg h-spr (ifield f-reg)) (and 16bval #xFF))
696 (set (reg h-spr (sub (ifield f-reg) 1))
697 (and (srl 16bval 8) #xFF))
698 (set fr (reg h-spr (ifield f-reg)))
699 )
700 ; Original instruction
701 (set fr (sub fr 1))
702 )
703 (if (not (zflag fr))
704 (skip 1)))
705 ()
706)
707
708(dni decsnzw_fr "Skip if W=fr-1 not zero"
709 ()
710 "decsnz W,$fr"
711 (+ OP6_DECSNZ DIR_TO_W fr)
712 (sequence ()
713 (set w (sub fr 1))
714 (if (not (zflag w))
715 (skip 1)))
716 ()
717)
718
719(dni subcw_fr "Subract w/carry W,fr"
720 ()
721 "subc W,$fr"
722 (+ OP6_SUBC DIR_TO_W fr)
723 (sequence ((QI result) (BI newcbit))
724 (set newcbit (not (sub-cflag fr w (not cbit))))
725 (set dcbit (not (sub-dcflag fr w (not cbit))))
726 (set result (subc fr w (not cbit)))
727 (set zbit (zflag result))
728 (set cbit newcbit)
729 (set w result))
730 ()
731)
732
733(dni subcfr_w "Subtract w/carry fr,W"
734 ()
735 "subc $fr,W"
736 (+ OP6_SUBC DIR_NOTTO_W fr)
737 (sequence ((QI result) (BI newcbit) (QI isLreg) (HI 16bval))
738 (set newcbit (not (sub-cflag fr w (not cbit))))
739 (set dcbit (not (sub-dcflag fr w (not cbit))))
740 (LregCheck isLreg (ifield f-reg))
741 ;; If fr is an Lreg, then we have to do 16-bit arithmetic.
742 ;; We can take advantage of the fact that by a lucky
743 ;; coincidence, the address of register xxxH is always
744 ;; one lower than the address of register xxxL.
745 (if (eq isLreg #x1)
746 (sequence()
747 ; Create the 16 bit value
748 (set 16bval (reg h-spr (sub (ifield f-reg) 1)))
749 (set 16bval (sll 16bval 8))
750 (set 16bval (or 16bval (and (reg h-spr (ifield f-reg)) #xFF)))
751 ; New 16 bit instruction
752 (set 16bval (subc HI 16bval w (not cbit)))
753 ; Separate the 16 bit values into the H and L regs
754 (set (reg h-spr (ifield f-reg)) (and 16bval #xFF))
755 (set (reg h-spr (sub (ifield f-reg) 1))
756 (and (srl 16bval 8) #xFF))
757 (set result (reg h-spr (ifield f-reg)))
758 )
759 ; Original instruction
760 (set result (subc fr w (not cbit)))
761 )
762
763
764 (set zbit (zflag result))
765 (set cbit newcbit)
766 (set fr result))
767 ()
768)
769
770
771(dni pop_fr "Pop fr"
772 ()
773 "pop $fr"
774 (+ OP6_POP (f-dir 1) fr)
775 (sequence()
776 (set fr (c-call QI "pop"))
777 (c-call VOID "adjuststackptr" (const 1))
778 )
779 ()
780)
781
782(dni push_fr "Push fr"
783 ()
784 "push $fr"
785 (+ OP6_POP (f-dir 0) fr)
786 (sequence()
787 (c-call "push" fr)
788 (c-call VOID "adjuststackptr" (const -1))
789 )
790 ()
791)
792
793(dni csew_fr "Skip if equal W,fr"
794 ()
795 "cse W,$fr"
796 (+ OP6_CSE (f-dir 1) fr)
797 (if (eq w fr)
798 (skip 1))
799 ()
800)
801
802(dni csnew_fr "Skip if not-equal W,fr"
803 ()
804 "csne W,$fr"
805 (+ OP6_CSE (f-dir 0) fr)
806 (if (not (eq w fr))
807 (skip 1))
808 ()
809)
810
811;;(dni csaw_fr "Skip if W above fr"
812;; ((MACH ip2022ext))
813;; "csa W,$fr"
814;; (+ OP6_CSAB (f-dir 1) fr)
815;; (if (gt w fr)
816;; (skip 1))
817;; ()
818;;)
819
820;;(dni csbw_fr "Skip if W below fr"
821;; ((MACH ip2022ext))
822;; "csb W,$fr"
823;; (+ OP6_CSAB (f-dir 0) fr)
824;; (if (lt w fr)
825;; (skip 1))
826;; ()
827;;)
828
829(dni incsz_fr "Skip if fr++ zero"
830 ()
831 "incsz $fr"
832 (+ OP6_INCSZ DIR_NOTTO_W fr)
833 (sequence ((QI isLreg) (HI 16bval))
834 (LregCheck isLreg (ifield f-reg))
835 ;; If fr is an Lreg, then we have to do 16-bit arithmetic.
836 ;; We can take advantage of the fact that by a lucky
837 ;; coincidence, the address of register xxxH is always
838 ;; one lower than the address of register xxxL.
839 (if (eq isLreg #x1)
840 (sequence()
841 ; Create the 16 bit value
842 (set 16bval (reg h-spr (sub (ifield f-reg) 1)))
843 (set 16bval (sll 16bval 8))
844 (set 16bval (or 16bval (and (reg h-spr (ifield f-reg)) #xFF)))
845 ; New 16 bit instruction
846 (set 16bval (add HI 16bval 1))
847 ; Separate the 16 bit values into the H and L regs
848 (set (reg h-spr (ifield f-reg)) (and 16bval #xFF))
849 (set (reg h-spr (sub (ifield f-reg) 1))
850 (and (srl 16bval 8) #xFF))
851 (set fr (reg h-spr (ifield f-reg)))
852 )
853 ; Original instruction
854 (set fr (add fr 1))
855 )
856 (if (zflag fr)
857 (skip 1)))
858 ()
859)
860
861(dni incszw_fr "Skip if W=fr+1 zero"
862 ()
863 "incsz W,$fr"
864 (+ OP6_INCSZ DIR_TO_W fr)
865 (sequence ()
866 (set w (add fr 1))
867 (if (zflag w)
868 (skip 1)))
869 ()
870)
871
872(dni swap_fr "Swap fr nibbles"
873 ()
874 "swap $fr"
875 (+ OP6_SWAP DIR_NOTTO_W fr)
876 (set fr (or (and (sll fr 4) #xf0)
877 (and (srl fr 4) #x0f)))
878 ()
879)
880
881(dni swapw_fr "Swap fr nibbles into W"
882 ()
883 "swap W,$fr"
884 (+ OP6_SWAP DIR_TO_W fr)
885 (set w (or (and (sll fr 4) #xf0)
886 (and (srl fr 4) #x0f)))
887 ()
888)
889
890(dni rl_fr "Rotate fr left with carry"
891 ()
892 "rl $fr"
893 (+ OP6_RL DIR_NOTTO_W fr)
894 (sequence ((QI newfr) (BI newc))
895 (set newc (and fr #x80))
896 (set newfr (or (sll fr 1) (if QI cbit 1 0)))
897 (set cbit (if QI newc 1 0))
898 (set fr newfr))
899 ()
900)
901
902(dni rlw_fr "Rotate fr left with carry into W"
903 ()
904 "rl W,$fr"
905 (+ OP6_RL DIR_TO_W fr)
906 (sequence ((QI newfr) (BI newc))
907 (set newc (and fr #x80))
908 (set newfr (or (sll fr 1) (if QI cbit 1 0)))
909 (set cbit (if QI newc 1 0))
910 (set w newfr))
911 ()
912)
913
914(dni rr_fr "Rotate fr right with carry"
915 ()
916 "rr $fr"
917 (+ OP6_RR DIR_NOTTO_W fr)
918 (sequence ((QI newfr) (BI newc))
919 (set newc (and fr #x01))
920 (set newfr (or (srl fr 1) (if QI cbit #x80 #x00)))
921 (set cbit (if QI newc 1 0))
922 (set fr newfr))
923 ()
924)
925
926(dni rrw_fr "Rotate fr right with carry into W"
927 ()
928 "rr W,$fr"
929 (+ OP6_RR DIR_TO_W fr)
930 (sequence ((QI newfr) (BI newc))
931 (set newc (and fr #x01))
932 (set newfr (or (srl fr 1) (if QI cbit #x80 #x00)))
933 (set cbit (if QI newc 1 0))
934 (set w newfr))
935 ()
936)
937
938(dni decsz_fr "Skip if fr-- zero"
939 ()
940 "decsz $fr"
941 (+ OP6_DECSZ DIR_NOTTO_W fr)
942 (sequence ((QI isLreg) (HI 16bval))
943 (LregCheck isLreg (ifield f-reg))
944 ;; If fr is an Lreg, then we have to do 16-bit arithmetic.
945 ;; We can take advantage of the fact that by a lucky
946 ;; coincidence, the address of register xxxH is always
947 ;; one lower than the address of register xxxL.
948 (if (eq isLreg #x1)
949 (sequence()
950 ; Create the 16 bit value
951 (set 16bval (reg h-spr (sub (ifield f-reg) 1)))
952 (set 16bval (sll 16bval 8))
953 (set 16bval (or 16bval (and (reg h-spr (ifield f-reg)) #xFF)))
954 ; New 16 bit instruction
955 (set 16bval (sub HI 16bval 1))
956 ; Separate the 16 bit values into the H and L regs
957 (set (reg h-spr (ifield f-reg)) (and 16bval #xFF))
958 (set (reg h-spr (sub (ifield f-reg) 1))
959 (and (srl 16bval 8) #xFF))
960 (set fr (reg h-spr (ifield f-reg)))
961 )
962 ; Original instruction
963 (set fr (sub fr 1))
964 )
965 (if (zflag fr)
966 (skip 1)))
967 ()
968)
969
970(dni decszw_fr "Skip if W=fr-1 zero"
971 ()
972 "decsz W,$fr"
973 (+ OP6_DECSZ DIR_TO_W fr)
974 (sequence ()
975 (set w (sub fr 1))
976 (if (zflag w)
977 (skip 1)))
978 ()
979)
980
981(dni inc_fr "Increment fr"
982 ()
983 "inc $fr"
984 (+ OP6_INC DIR_NOTTO_W fr)
985 (sequence ((QI isLreg) (HI 16bval))
986 (LregCheck isLreg (ifield f-reg))
987 ;; If fr is an Lreg, then we have to do 16-bit arithmetic.
988 ;; We can take advantage of the fact that by a lucky
989 ;; coincidence, the address of register xxxH is always
990 ;; one lower than the address of register xxxL.
991 (if (eq isLreg #x1)
992 (sequence()
993 ; Create the 16 bit value
994 (set 16bval (reg h-spr (sub (ifield f-reg) 1)))
995 (set 16bval (sll 16bval 8))
996 (set 16bval (or 16bval (and (reg h-spr (ifield f-reg)) #xFF)))
997 ; New 16 bit instruction
998 (set 16bval (add HI 16bval 1))
999 ; Separate the 16 bit values into the H and L regs
1000 (set (reg h-spr (ifield f-reg)) (and 16bval #xFF))
1001 (set (reg h-spr (sub (ifield f-reg) 1))
1002 (and (srl 16bval 8) #xFF))
1003 (set fr (reg h-spr (ifield f-reg)))
1004 )
1005 ; Original instruction
1006 (set fr (add fr 1))
1007 )
1008 (set zbit (zflag fr)))
1009 ()
1010)
1011
1012(dni incw_fr "Increment fr into w"
1013 ()
1014 "inc W,$fr"
1015 (+ OP6_INC DIR_TO_W fr)
1016 (sequence ()
1017 (set w (add fr 1))
1018 (set zbit (zflag w)))
1019 ()
1020)
1021
1022(dni not_fr "Invert fr"
1023 ()
1024 "not $fr"
1025 (+ OP6_NOT DIR_NOTTO_W fr)
1026 (sequence ()
1027 (set fr (inv fr))
1028 (set zbit (zflag fr)))
1029 ()
1030)
1031
1032(dni notw_fr "Invert fr into w"
1033 ()
1034 "not W,$fr"
1035 (+ OP6_NOT DIR_TO_W fr)
1036 (sequence ()
1037 (set w (inv fr))
1038 (set zbit (zflag w)))
1039 ()
1040)
1041
1042(dni test_fr "Test fr"
1043 ()
1044 "test $fr"
1045 (+ OP6_TEST DIR_NOTTO_W fr)
1046 (sequence ()
1047 (set zbit (zflag fr)))
1048 ()
1049)
1050
1051(dni movw_l "MOV W,literal"
1052 ()
1053 "mov W,#$lit8"
1054 (+ OP4_LITERAL OP4MID_MOV_L lit8)
1055 (set w lit8)
1056 ()
1057)
1058
1059(dni movfr_w "Move/test w into fr"
1060 ()
1061 "mov $fr,W"
1062 (+ OP6_OTHER1 DIR_NOTTO_W fr)
1063 (set fr w)
1064 ()
1065)
1066
1067(dni movw_fr "Move/test fr into w"
1068 ()
1069 "mov W,$fr"
1070 (+ OP6_TEST DIR_TO_W fr)
1071 (sequence ()
1072 (set w fr)
1073 (set zbit (zflag w)))
1074 ()
1075)
1076
1077
1078(dni addfr_w "Add fr,W"
1079 ()
1080 "add $fr,W"
1081 (+ OP6_ADD DIR_NOTTO_W fr)
1082 (sequence ((QI result) (QI isLreg) (HI 16bval))
1083 (set cbit (add-cflag w fr 0))
1084 (set dcbit (add-dcflag w fr 0))
1085 (LregCheck isLreg (ifield f-reg))
1086
1087 ;; If fr is an Lreg, then we have to do 16-bit arithmetic.
1088 ;; We can take advantage of the fact that by a lucky
1089 ;; coincidence, the address of register xxxH is always
1090 ;; one lower than the address of register xxxL.
1091 (if (eq isLreg #x1)
1092 (sequence()
1093 (set 16bval (reg h-spr (sub (ifield f-reg) 1)))
1094 (set 16bval (sll 16bval 8))
1095 (set 16bval (or 16bval (and (reg h-spr (ifield f-reg)) #xFF)))
1096 (set 16bval (add HI (and w #xFF) 16bval))
1097 (set (reg h-spr (ifield f-reg)) (and 16bval #xFF))
1098 (set (reg h-spr (sub (ifield f-reg) 1))
1099 (and (srl 16bval 8) #xFF))
1100 (set result (reg h-spr (ifield f-reg)))
1101 )
1102 (set result (addc w fr 0)) ;; else part
1103 )
1104 (set zbit (zflag result))
1105 (set fr result))
1106 ()
1107)
1108
1109(dni addw_fr "Add W,fr"
1110 ()
1111 "add W,$fr"
1112 (+ OP6_ADD DIR_TO_W fr)
1113 (sequence ((QI result))
1114 (set cbit (add-cflag w fr 0))
1115 (set dcbit (add-dcflag w fr 0))
1116 (set result (addc w fr 0))
1117 (set zbit (zflag result))
1118 (set w result))
1119 ()
1120)
1121
1122(dni xorfr_w "XOR fr,W"
1123 ()
1124 "xor $fr,W"
1125 (+ OP6_XOR DIR_NOTTO_W fr)
1126 (sequence ()
1127 (set fr (xor w fr))
1128 (set zbit (zflag fr)))
1129 ()
1130)
1131
1132(dni xorw_fr "XOR W,fr"
1133 ()
1134 "xor W,$fr"
1135 (+ OP6_XOR DIR_TO_W fr)
1136 (sequence ()
1137 (set w (xor fr w))
1138 (set zbit (zflag w)))
1139 ()
1140)
1141
1142(dni andfr_w "AND fr,W"
1143 ()
1144 "and $fr,W"
1145 (+ OP6_AND DIR_NOTTO_W fr)
1146 (sequence ()
1147 (set fr (and w fr))
1148 (set zbit (zflag fr)))
1149 ()
1150)
1151
1152(dni andw_fr "AND W,fr"
1153 ()
1154 "and W,$fr"
1155 (+ OP6_AND DIR_TO_W fr)
1156 (sequence ()
1157 (set w (and fr w))
1158 (set zbit (zflag w)))
1159 ()
1160)
1161
1162(dni orfr_w "OR fr,W"
1163 ()
1164 "or $fr,W"
1165 (+ OP6_OR DIR_NOTTO_W fr)
1166 (sequence ()
1167 (set fr (or w fr))
1168 (set zbit (zflag fr)))
1169 ()
1170)
1171
1172(dni orw_fr "OR W,fr"
1173 ()
1174 "or W,$fr"
1175 (+ OP6_OR DIR_TO_W fr)
1176 (sequence ()
1177 (set w (or fr w))
1178 (set zbit (zflag w)))
1179 ()
1180)
1181
1182(dni dec_fr "Decrement fr"
1183 ()
1184 "dec $fr"
1185 (+ OP6_DEC DIR_NOTTO_W fr)
1186 (sequence ((QI isLreg) (HI 16bval))
1187 (LregCheck isLreg (ifield f-reg))
1188 ;; If fr is an Lreg, then we have to do 16-bit arithmetic.
1189 ;; We can take advantage of the fact that by a lucky
1190 ;; coincidence, the address of register xxxH is always
1191 ;; one lower than the address of register xxxL.
1192 (if (eq isLreg #x1)
1193 (sequence()
1194 ; Create the 16 bit value
1195 (set 16bval (reg h-spr (sub (ifield f-reg) 1)))
1196 (set 16bval (sll 16bval 8))
1197 (set 16bval (or 16bval (and (reg h-spr (ifield f-reg)) #xFF)))
1198 ; New 16 bit instruction
1199 (set 16bval (sub HI 16bval 1))
1200 ; Separate the 16 bit values into the H and L regs
1201 (set (reg h-spr (ifield f-reg)) (and 16bval #xFF))
1202 (set (reg h-spr (sub (ifield f-reg) 1))
1203 (and (srl 16bval 8) #xFF))
1204 (set fr (reg h-spr (ifield f-reg)))
1205 )
1206 ; Original instruction
1207 (set fr (sub fr 1))
1208 )
1209 (set zbit (zflag fr)))
1210 ()
1211)
1212
1213(dni decw_fr "Decrement fr into w"
1214 ()
1215 "dec W,$fr"
1216 (+ OP6_DEC DIR_TO_W fr)
1217 (sequence ()
1218 (set w (sub fr 1))
1219 (set zbit (zflag w)))
1220 ()
1221)
1222
1223(dni subfr_w "Sub fr,W"
1224 ()
1225 "sub $fr,W"
1226 (+ OP6_SUB DIR_NOTTO_W fr)
1227 (sequence ((QI result) (QI isLreg) (HI 16bval))
1228 (set cbit (not (sub-cflag fr w 0)))
1229 (set dcbit (not (sub-dcflag fr w 0)))
1230 (LregCheck isLreg (ifield f-reg))
1231 ;; If fr is an Lreg, then we have to do 16-bit arithmetic.
1232 ;; We can take advantage of the fact that by a lucky
1233 ;; coincidence, the address of register xxxH is always
1234 ;; one lower than the address of register xxxL.
1235 (if (eq isLreg #x1)
1236 (sequence()
1237 ; Create the 16 bit value
1238 (set 16bval (reg h-spr (sub (ifield f-reg) 1)))
1239 (set 16bval (sll 16bval 8))
1240 (set 16bval (or 16bval (and (reg h-spr (ifield f-reg)) #xFF)))
1241 ; New 16 bit instruction
1242 (set 16bval (sub HI 16bval (and w #xFF)))
1243 ; Separate the 16 bit values into the H and L regs
1244 (set (reg h-spr (ifield f-reg)) (and 16bval #xFF))
1245 (set (reg h-spr (sub (ifield f-reg) 1))
1246 (and (srl 16bval 8) #xFF))
1247 (set result (reg h-spr (ifield f-reg)))
1248 )
1249 ; Original instruction
1250 (set result (subc fr w 0))
1251 )
1252 (set zbit (zflag result))
1253 (set fr result))
1254 ()
1255)
1256
1257(dni subw_fr "Sub W,fr"
1258 ()
1259 "sub W,$fr"
1260 (+ OP6_SUB DIR_TO_W fr)
1261 (sequence ((QI result))
1262 (set cbit (not (sub-cflag fr w 0)))
1263 (set dcbit (not (sub-dcflag fr w 0)))
1264 (set result (subc fr w 0))
1265 (set zbit (zflag result))
1266 (set w result))
1267 ()
1268)
1269
1270(dni clr_fr "Clear fr"
1271 ()
1272 "clr $fr"
1273 (+ OP6_OTHER2 (f-dir 1) fr)
1274 (sequence ()
1275 (set fr 0)
1276 (set zbit (zflag fr)))
1277 ()
1278)
1279
1280(dni cmpw_fr "CMP W,fr"
1281 ()
1282 "cmp W,$fr"
1283 (+ OP6_OTHER2 (f-dir 0) fr)
1284 (sequence ()
1285 (set cbit (not (sub-cflag fr w 0)))
1286 (set dcbit (not (sub-dcflag fr w 0)))
1287 (set zbit (zflag (sub w fr))))
1288 ()
1289)
1290
1291(dni speed "Set speed"
1292 ()
1293 "speed #$lit8"
1294 (+ (f-op8 1) lit8)
1295 (set (reg h-registers #x0E) lit8)
1296 ()
1297)
1298
1299(dni ireadi "Insn memory read with increment"
1300 ()
1301 "ireadi"
1302 (+ OP6_OTHER1 (f-op6-10low #x1D))
1303 (c-call "do_insn_read")
1304 ()
1305)
1306
1307(dni iwritei "Insn memory write with increment"
1308 ()
1309 "iwritei"
1310 (+ OP6_OTHER1 (f-op6-10low #x1C))
1311 (c-call "do_insn_write")
1312 ()
1313)
1314
1315(dni fread "Flash read"
1316 ()
1317 "fread"
1318 (+ OP6_OTHER1 (f-op6-10low #x1B))
1319 (c-call "do_flash_read")
1320 ()
1321)
1322
1323(dni fwrite "Flash write"
1324 ()
1325 "fwrite"
1326 (+ OP6_OTHER1 (f-op6-10low #x1A))
1327 (c-call "do_flash_write")
1328 ()
1329)
1330
1331(dni iread "Insn memory read"
1332 ()
1333 "iread"
1334 (+ OP6_OTHER1 (f-op6-10low #x19))
1335 (c-call "do_insn_read")
1336 ()
1337)
1338
1339(dni iwrite "Insn memory write"
1340 ()
1341 "iwrite"
1342 (+ OP6_OTHER1 (f-op6-10low #x18))
1343 (c-call "do_insn_write")
1344 ()
1345)
1346
1347(dni page "Set insn page"
1348 (EXT-SKIP-INSN)
1349 ;"page $page3"
1350 "page $addr16p"
1351 ;(+ OP6_OTHER1 (f-op6-7low #x2) page3)
1352 ;(set pabits (srl page3 13))
1353 (+ OP6_OTHER1 (f-op6-7low #x2) addr16p)
1354 (set pabits addr16p)
1355 ()
1356)
1357
1358(dni system "System call"
1359 ()
1360 "system"
1361 (+ OP6_OTHER1 (f-op6-10low #xff))
1362 (c-call "do_system")
1363 ()
1364)
1365
1366(dni reti "Return from interrupt"
1367 ()
1368 "reti #$reti3"
1369 (+ OP6_OTHER1 (f-op6-7low #x1) reti3)
1370 (c-call "do_reti" reti3)
1371 ()
1372)
1373
1374(dni ret "Return"
1375 ()
1376 "ret"
1377 (+ OP6_OTHER1 (f-op6-10low #x07))
1378 (sequence ((USI new_pc))
1379 (set new_pc (c-call UHI "pop_pc_stack"))
1380 (set pabits (srl new_pc 13))
1381 (set pc new_pc))
1382 ()
1383)
1384
1385(dni int "Software interrupt"
1386 ()
1387 "int"
1388 (+ OP6_OTHER1 (f-op6-10low #x6))
1389 (nop)
1390 ()
1391)
1392
1393(dni breakx "Breakpoint with extended skip"
1394 (EXT-SKIP-INSN)
1395 "breakx"
1396 (+ OP6_OTHER1 (f-op6-10low #x5))
1397 (c-call "do_break" pc)
1398 ()
1399)
1400
1401(dni cwdt "Clear watchdog timer"
1402 ()
1403 "cwdt"
1404 (+ OP6_OTHER1 (f-op6-10low #x4))
1405 (c-call "do_clear_wdt")
1406 ()
1407)
1408
1409(dni ferase "Flash erase"
1410 ()
1411 "ferase"
1412 (+ OP6_OTHER1 (f-op6-10low #x3))
1413 (c-call "do_flash_erase")
1414 ()
1415)
1416
1417(dni retnp "Return, no page"
1418 ()
1419 "retnp"
1420 (+ OP6_OTHER1 (f-op6-10low #x2))
1421 (sequence ((USI new_pc))
1422 (set new_pc (c-call UHI "pop_pc_stack"))
1423 (set pc new_pc))
1424 ()
1425)
1426
1427(dni break "Breakpoint"
1428 ()
1429 "break"
1430 (+ OP6_OTHER1 (f-op6-10low #x1))
1431 (c-call "do_break" pc)
1432 ()
1433)
1434
1435(dni nop "No operation"
1436 ()
1437 "nop"
1438 (+ OP6_OTHER1 (f-op6-10low #x0))
1439 (nop)
1440 ()
1441)
1442
1443
1444; Macro instructions
1445(dnmi sc "Skip on carry"
1446 ()
1447 "sc"
1448 (emit sb (bitno 0) (fr #xB)) ; sb status.0
1449)
1450
1451(dnmi snc "Skip on no carry"
1452 ()
1453 "snc"
1454 (emit snb (bitno 0) (fr #xB)) ; snb status.0
1455)
1456
1457(dnmi sz "Skip on zero"
1458 ()
1459 "sz"
1460 (emit sb (bitno 2) (fr #xB)) ; sb status.2
1461)
1462
1463(dnmi snz "Skip on no zero"
1464 ()
1465 "snz"
1466 (emit snb (bitno 2) (fr #xB)) ; snb status.2
1467)
1468
1469(dnmi skip "Skip always"
1470 (SKIPA)
1471 "skip"
1472 (emit snb (bitno 0) (fr 9)) ; snb pcl.0 | (pcl&1)<<12
1473)
1474
1475(dnmi skipb "Skip always"
1476 (SKIPA)
1477 "skip"
1478 (emit sb (bitno 0) (fr 9)) ; sb pcl.0 | (pcl&1)<<12
1479)
1480