OpenCores
URL https://opencores.org/ocsvn/open8_urisc/open8_urisc/trunk

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [cpu/] [ip2k.cpu] - Blame information for rev 249

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 161 khays
; 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
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.