ip2k.cpu 38 KB

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