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 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 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 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 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 1481