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