-
Notifications
You must be signed in to change notification settings - Fork 23
/
TI430Common.sinc
1649 lines (1469 loc) · 68.7 KB
/
TI430Common.sinc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#
# TI MSP430
#
# Texas Instruments microcontroller 16-bit CPU
#
# Memory Architecture
#
define endian=$(ENDIAN);
define alignment=2;
define space RAM type=ram_space size=$(REG_SIZE) default;
define space register type=register_space size=2;
#
# General Registers
#
define register offset=0x0000 size=$(REG_SIZE) [
PC # R0 # Program Counter
SP # R1 # Stack Pointer
SR # R2 # Status Register
R3 # R3 # Constant Generator
#Available for general use:
R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15
#None:
None
];
@if REG_SIZE == "4"
define register offset=0x0000 size=2 [
PC_16 _ SP_16 _ SR_16 _ R3_16 _ R4_16 _ R5_16 _ R6_16 _ R7_16 _
R8_16 _ R9_16 _ R10_16 _ R11_16 _ R12_16 _ R13_16 _ R14_16 _ R15_16 _
];
define register offset=0x0000 size=1 [
PC_lo PC_hi _ _ # R0 # Program Counter
SP_lo SP_hi _ _ # R1 # Stack Pointer
SR_lo SR_hi _ _ # R2 # Status Register
R3_lo R3_hi _ _ # R3 # Constant Generator
#Available for general use:
R4_lo R4_hi _ _
R5_lo R5_hi _ _
R6_lo R6_hi _ _
R7_lo R7_hi _ _
R8_lo R8_hi _ _
R9_lo R9_hi _ _
R10_lo R10_hi _ _
R11_lo R11_hi _ _
R12_lo R12_hi _ _
R13_lo R13_hi _ _
R14_lo R14_hi _ _
R15_lo R15_hi _ _
#None:
None_lo None_hi _ _
];
@else
define register offset=0x0000 size=1 [
PC_lo PC_hi # R0 # Program Counter
SP_lo SP_hi # R1 # Stack Pointer
SR_lo SR_hi # R2 # Status Register
R3_lo R3_hi # R3 # Constant Generator
#Available for general use:
R4_lo R4_hi
R5_lo R5_hi
R6_lo R6_hi
R7_lo R7_hi
R8_lo R8_hi
R9_lo R9_hi
R10_lo R10_hi
R11_lo R11_hi
R12_lo R12_hi
R13_lo R13_hi
R14_lo R14_hi
R15_lo R15_hi
#None:
None_lo None_hi
];
@endif
define register offset=0x1000 size=4 contextreg;
define context contextreg
# NOTE: Only instructions that don't use immediates (except ones from constant generator) can
# use the repeat feature.
# NOTE: The POPM/PUSM have a starting register & # of register to pop/push. We need to track
# that info in context for the subtables that do the work.
ctx_isHi=(0,0) noflow # Used in pspec to flag msp430 instruction > 64k
ctx_al=(1,1) noflow # extension word al field
ctx_ctregdest=(2,5) noflow # extension word dest register/immediate field
ctx_ctregdests=(2,5) signed noflow # signed version of above
ctx_repreg=(2,5) noflow # register repeat count comes from.
ctx_regsrc=(6,9) noflow # extension word src register/immediate field
ctx_regsrcs=(6,9) signed noflow # signed version of above
ctx_zc=(10,10) noflow # extension word zero carry field
ctx_num=(11,11) noflow # is repetition field a # or register
ctx_haveext=(12,14) noflow # used to track type of extension word used
ctx_popreg_set=(15,18) noflow # used to set register for POPM/PUSHM instructions
ctx_popreg=(15,18) noflow # display register, linked for POPM/PUSHM instructions
ctx_count=(19,22) noflow # tracks count of registers for POPM/PUSHM
ctx_mreg=(23,26) noflow # register being accessed in POPM/PUSHM
;
define register offset=0x2000 size=1 [ CNT ];
#
# Tokens
#
define token instr16(16)
op16_0_8 = (0, 7)
op16_4_4 = (4, 7)
op16_0_4 = (0, 3)
op16_7_9 = (7, 15)
op16_8_4 = (8, 11)
op16_8_8 = (8, 15)
op16_12_4 = (12, 15)
opext_11_5 = (11, 15)
op16_7_1 = (7, 7)
op16_13_3 = (13, 15)
src = (0, 3)
dest = (0, 3)
as = (4, 5)
bow = (6, 6)
insid = (4, 7)
insidbig = (4, 9)
reg16_0_4 = (0, 3)
dest_0_4 = (0, 3)
imm_0_4 = (0, 4)
reg_Direct16_0_4 = (0, 3)
reg_Direct16_0_4W = (0, 3)
reg_Indexed16_0_4 = (0, 3)
reg_InDirect16_0_4 = (0, 3)
dest_Direct16_0_4 = (0, 3)
dest_Indexed16_0_4 = (0, 3)
dest_Direct_lo = (0, 3)
dest_Direct_hi = (0, 3)
condition = (10, 12)
off16 = (0, 9) signed
off16_8_2 = (8, 9)
off16_4_4 = (4, 7)
off16_0_4 = (0, 3)
zc = (8, 8)
ad = (7, 7)
al = (6, 6)
imm_4_4 = (4, 7)
imm_8_4 = (8, 11)
src_8_4 = (8, 11)
src16_8_4 = (8, 11)
src_Direct16_8_4 = (8, 11)
reg_Direct16_8_4W = (8, 11)
src_InDirect16_8_4 = (8, 11)
src_Indexed16_8_4 = (8, 11)
src_Direct_lo = (8, 11)
src_Direct_hi = (8, 11)
src_ext = (7, 10)
rrn = (10, 11)
imm_0_16 = (0, 15)
imms_0_16 = (0, 15) signed
indexExtWord16_0_16 = (0, 15)
indexExtWord16_0_16s = (0, 15) signed
indexExt2Word16_0_16 = (0, 15)
indexExt2Word16_0_16s = (0, 15) signed
;
#
# Attach(s)
#
attach variables [ src_8_4
dest_0_4
reg_Direct16_0_4
src_Direct16_8_4
dest_Direct16_0_4
ctx_popreg
ctx_repreg ] [ PC SP SR R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ];
attach variables [ dest_Direct_lo src_Direct_lo] [ PC_lo SP_lo SR_lo _ R4_lo R5_lo R6_lo R7_lo
R8_lo R9_lo R10_lo R11_lo R12_lo R13_lo R14_lo R15_lo ];
attach variables [ dest_Direct_hi src_Direct_hi] [ PC_hi SP_hi SR_hi _ R4_hi R5_hi R6_hi R7_hi
R8_hi R9_hi R10_hi R11_hi R12_hi R13_hi R14_hi R15_hi ];
attach variables [ reg_Indexed16_0_4
src_Indexed16_8_4
dest_Indexed16_0_4 ] [ None SP _ _ R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ];
attach variables [ reg_InDirect16_0_4
src_InDirect16_8_4 ] [ PC SP _ _ R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15 ];
@if REG_SIZE == "4"
attach variables [reg_Direct16_0_4W reg_Direct16_8_4W] [PC_16 SP_16 SR_16 _ R4_16 R5_16 R6_16 R7_16 R8_16 R9_16 R10_16 R11_16 R12_16 R13_16 R14_16 R15_16];
@else
attach variables [reg_Direct16_0_4W reg_Direct16_8_4W] [PC SP SR _ R4 R5 R6 R7 R8 R9 R10 R11 R12 R13 R14 R15];
@endif
SRC16_8_4: src_Direct16_8_4 is src_Direct16_8_4 & reg_Direct16_8_4W {export reg_Direct16_8_4W;}
DST16_0_4: dest_Direct16_0_4 is dest_Direct16_0_4 & reg_Direct16_0_4W {export reg_Direct16_0_4W;}
SRC8_8_4: src_Direct16_8_4 is src_Direct16_8_4 & src_Direct_lo {export src_Direct_lo;}
DST8_0_4: reg_Direct16_0_4 is reg_Direct16_0_4 & dest_Direct_lo {export dest_Direct_lo;}
define pcodeop bcd_add; # Binary coded decimal (BCD) addition
####################################
# Status Register (SR) Map
####################################
# b15-b9: Reserved
# b8: V (overflow bit)
# b7: SCG1 (System Clock generator 1)
# b6: SCG0 (System Clock generator 0)
# b5: OSCOFF (Oscillator Off)
# b4: CPUOFF (CPU off)
# b3: GIE (General Interrupt Enable)
# b2: N (Negative Bit) (Word = bit 15, Byte = bit 7)(sign bit)
# b1: Z (Zero Bit)
# b0: C (Carry Bit)
####################################
@define CARRY "SR[0,1]"
@define ZERO "SR[1,1]"
@define SIGN "SR[2,1]"
@define OVERFLOW "SR[8,1]"
@define GIE "SR[3,1]"
#
# Sub Constructors
#
#-----------------------------------------------
# B/W: Byte or Word operation
# 0: Word Operation
# 1: Byte Operation
#-----------------------------------------------
@if REG_SIZE == "4"
AMASK: val is ctx_isHi=1 [ val = 0xFFFF; ] { export *[const]:4 val; }
AMASK: val is ctx_isHi=0 [ val = 0xFFFFF; ] { export *[const]:4 val; }
@else
AMASK: val is epsilon [ val = 0xFFFF; ] { export *[const]:2 val; }
@endif
#-----------------------------------------------
#
# REGISTER (REG)
#
# The REG modes are used for the 1 operand form instructions
#
#-----------------------------------------------
REG_W_AS: DST16_0_4 is DST16_0_4 & as=0x0 & bow=0x0 {export DST16_0_4;} # Word/Register Direct (Rn):
REG_W_AS: indexExtWord16_0_16s^"("^reg_Indexed16_0_4^")" is reg_Indexed16_0_4 & as=0x1 & bow=0x0 & AMASK ; indexExtWord16_0_16s {tmp:$(REG_SIZE) = (reg_Indexed16_0_4 + indexExtWord16_0_16s) & AMASK; export *:2 tmp;}
REG_W_AS: "@"^reg_InDirect16_0_4 is reg_InDirect16_0_4 & as=0x2 & bow=0x0 {export *:2 reg_InDirect16_0_4;} # Word/Register Indirect (@Rn):
REG_W_AS: "@"^reg_InDirect16_0_4^"+" is reg_InDirect16_0_4 & as=0x3 & bow=0x0 {export *:2 reg_InDirect16_0_4;} # Word/Register Indirect Autoincrement (@Rn+):
REG_W_AS: labelCalc is reg16_0_4=0x0 & as=0x1 & bow=0x0 & AMASK; indexExtWord16_0_16 [labelCalc = inst_start + 2 + indexExtWord16_0_16; ] {tmp:$(REG_SIZE) = labelCalc & AMASK; export *:2 tmp; } # Symbolic
REG_W_AS: "#"^indexExtWord16_0_16 is reg16_0_4=0x0 & as=0x3 & bow=0x0 ; indexExtWord16_0_16 {export *[const]:2 indexExtWord16_0_16; } # Immediate
REG_W_AS: "&"^indexExtWord16_0_16 is reg16_0_4=0x2 & as=0x1 & bow=0x0 ; indexExtWord16_0_16 {export *:2 indexExtWord16_0_16; } # Absolute
REG_W_AS: "#4" is reg16_0_4=0x2 & as=0x2 & bow=0x0 { export 4:2;} # Constant
REG_W_AS: "#8" is reg16_0_4=0x2 & as=0x3 & bow=0x0 { export 8:2;} # Constant
REG_W_AS: "#0" is reg16_0_4=0x3 & as=0x0 & bow=0x0 { export 0:2;} # Constant
REG_W_AS: "#1" is reg16_0_4=0x3 & as=0x1 & bow=0x0 { export 1:2;} # Constant
REG_W_AS: "#2" is reg16_0_4=0x3 & as=0x2 & bow=0x0 { export 2:2;} # Constant
REG_W_AS: "#-1" is reg16_0_4=0x3 & as=0x3 & bow=0x0 { export 0xffff:2;} # Constant
REG_W_AS_DEST: DST16_0_4 is DST16_0_4 & as=0x0 & bow=0x0 {export DST16_0_4;} # Word/Register Direct (Rn):
REG_W_AS_DEST: indexExtWord16_0_16s^"("^reg_Indexed16_0_4^")" is reg_Indexed16_0_4 & as=0x1 & bow=0x0 & AMASK ; indexExtWord16_0_16s {tmp:$(REG_SIZE) = (reg_Indexed16_0_4 + indexExtWord16_0_16s) & AMASK; export *:2 tmp;}
REG_W_AS_DEST: "@"^reg_InDirect16_0_4 is reg_InDirect16_0_4 & as=0x2 & bow=0x0 {export *:2 reg_InDirect16_0_4;} # Word/Register Indirect (@Rn):
REG_W_AS_DEST: "@"^reg_InDirect16_0_4^"+" is reg_InDirect16_0_4 & as=0x3 & bow=0x0 {export *:2 reg_InDirect16_0_4;} # Word/Register Indirect Autoincrement (@Rn+):
REG_W_AS_DEST: labelCalc is reg16_0_4=0x0 & as=0x1 & bow=0x0 & AMASK ; indexExtWord16_0_16 [labelCalc = inst_start + 2 + indexExtWord16_0_16; ] {tmp:$(REG_SIZE) = labelCalc & AMASK;export *:2 tmp; } # Symbolic
REG_W_AS_DEST: "&"^indexExtWord16_0_16 is reg16_0_4=0x2 & as=0x1 & bow=0x0 ; indexExtWord16_0_16 {export *:2 indexExtWord16_0_16; } # Absolute
#-----------------------------------------------
REG_B_AS: DST8_0_4 is DST8_0_4 & as=0x0 & bow=0x1 { export DST8_0_4;} # Word/Register Direct (Rn):
REG_B_AS: indexExtWord16_0_16s^"("^reg_Indexed16_0_4^")" is reg_Indexed16_0_4 & as=0x1 & bow=0x1 & AMASK ; indexExtWord16_0_16s {tmp:$(REG_SIZE) = (reg_Indexed16_0_4 + indexExtWord16_0_16s) & AMASK; export *:1 tmp;}
REG_B_AS: "@"^reg_InDirect16_0_4 is reg_InDirect16_0_4 & as=0x2 & bow=0x1 {export *:1 reg_InDirect16_0_4;} # Word/Register Indirect (@Rn):
REG_B_AS: "@"^reg_InDirect16_0_4^"+" is reg_InDirect16_0_4 & as=0x3 & bow=0x1 {export *:1 reg_InDirect16_0_4;} # Word/Register Indirect Autoincrement (@Rn+):
REG_B_AS: labelCalc is reg16_0_4=0x0 & as=0x1 & bow=0x1 & AMASK ; indexExtWord16_0_16 [labelCalc = inst_start + 2 + indexExtWord16_0_16; ] {tmp:$(REG_SIZE) = labelCalc & AMASK;export *:1 tmp; } # Symbolic
REG_B_AS: "#"^indexExtWord16_0_16 is reg16_0_4=0x0 & as=0x3 & bow=0x1 ; indexExtWord16_0_16 { export *[const]:1 indexExtWord16_0_16; } # Immediate
REG_B_AS: "&"^indexExtWord16_0_16 is reg16_0_4=0x2 & as=0x1 & bow=0x1 ; indexExtWord16_0_16 {export *:1 indexExtWord16_0_16; } # Absolute
REG_B_AS: "#4" is reg16_0_4=0x2 & as=0x2 & bow=0x1 { export 4:1;} # Constant
REG_B_AS: "#8" is reg16_0_4=0x2 & as=0x3 & bow=0x1 { export 8:1;} # Constant
REG_B_AS: "#0" is reg16_0_4=0x3 & as=0x0 & bow=0x1 { export 0:1;} # Constant
REG_B_AS: "#1" is reg16_0_4=0x3 & as=0x1 & bow=0x1 { export 1:1;} # Constant
REG_B_AS: "#2" is reg16_0_4=0x3 & as=0x2 & bow=0x1 { export 2:1;} # Constant
REG_B_AS: "#-1" is reg16_0_4=0x3 & as=0x3 & bow=0x1 { export 0xff:1;} # Constant
REG_B_AS_DEST: DST8_0_4 is DST8_0_4 & as=0x0 & bow=0x1 { export DST8_0_4;} # Word/Register Direct (Rn):
REG_B_AS_DEST: indexExtWord16_0_16s^"("^reg_Indexed16_0_4^")" is reg_Indexed16_0_4 & as=0x1 & bow=0x1 & AMASK ; indexExtWord16_0_16s {tmp:$(REG_SIZE) = (reg_Indexed16_0_4 + indexExtWord16_0_16s) & AMASK; export *:1 tmp;}
REG_B_AS_DEST: "@"^reg_InDirect16_0_4 is reg_InDirect16_0_4 & as=0x2 & bow=0x1 {export *:1 reg_InDirect16_0_4;} # Word/Register Indirect (@Rn):
REG_B_AS_DEST: "@"^reg_InDirect16_0_4^"+" is reg_InDirect16_0_4 & as=0x3 & bow=0x1 {export *:1 reg_InDirect16_0_4;} # Word/Register Indirect Autoincrement (@Rn+):
REG_B_AS_DEST: labelCalc is reg16_0_4=0x0 & as=0x1 & bow=0x1 & AMASK ; indexExtWord16_0_16 [labelCalc = inst_start + 2 + indexExtWord16_0_16; ] {tmp:$(REG_SIZE) = labelCalc & AMASK;export *:1 tmp; } # Symbolic
REG_B_AS_DEST: "&"^indexExtWord16_0_16 is reg16_0_4=0x2 & as=0x1 & bow=0x1 ; indexExtWord16_0_16 {export *:1 indexExtWord16_0_16; } # Absolute
#-----------------------------------------------
#
# SOURCE (SRC)
#
#-----------------------------------------------
SRC_W_AS: SRC16_8_4 is SRC16_8_4 & as=0x0 & bow=0x0 {export SRC16_8_4;} # Word/Register Direct (Rn):
SRC_W_AS: indexExtWord16_0_16s^"("^src_Indexed16_8_4^")" is src_Indexed16_8_4 & as=0x1 & bow=0x0 & AMASK ; indexExtWord16_0_16s {tmp:$(REG_SIZE) = (src_Indexed16_8_4 + indexExtWord16_0_16s) & AMASK; export *:2 tmp;}
SRC_W_AS: "@"^src_InDirect16_8_4 is src_InDirect16_8_4 & as=0x2 & bow=0x0 {export *:2 src_InDirect16_8_4;} # Word/Register Indirect (@Rn):
SRC_W_AS: "@"^src_InDirect16_8_4^"+" is src_InDirect16_8_4 & as=0x3 & bow=0x0 {export *:2 src_InDirect16_8_4;} # Word/Register Indirect Autoincrement (@Rn+):
SRC_W_AS: labelCalc is src16_8_4=0x0 & as=0x1 & bow=0x0 & AMASK ; indexExtWord16_0_16 [labelCalc = inst_start + 2 + indexExtWord16_0_16; ] {tmp:$(REG_SIZE) = labelCalc & AMASK;export *:2 tmp; } # Symbolic
SRC_W_AS: "#"^indexExtWord16_0_16 is src16_8_4=0x0 & as=0x3 & bow=0x0 ; indexExtWord16_0_16 {export *[const]:2 indexExtWord16_0_16; } # Immediate
SRC_W_AS: "&"^indexExtWord16_0_16 is src16_8_4=0x2 & as=0x1 & bow=0x0 ; indexExtWord16_0_16 {export *:2 indexExtWord16_0_16; } # Absolute
SRC_W_AS: "#4" is src16_8_4=0x2 & as=0x2 & bow=0x0 { export 4:2; } # Constant
SRC_W_AS: "#8" is src16_8_4=0x2 & as=0x3 & bow=0x0 { export 8:2; } # Constant
SRC_W_AS: "#0" is src16_8_4=0x3 & as=0x0 & bow=0x0 { export 0:2; } # Constant
SRC_W_AS: "#1" is src16_8_4=0x3 & as=0x1 & bow=0x0 { export 1:2; } # Constant
SRC_W_AS: "#2" is src16_8_4=0x3 & as=0x2 & bow=0x0 { export 2:2; } # Constant
SRC_W_AS: "#-1" is src16_8_4=0x3 & as=0x3 & bow=0x0 { export 0xffff:2; } # Constant
#-----------------------------------------------
SRC_B_AS: SRC8_8_4 is SRC8_8_4 & as=0x0 & bow=0x1 { export SRC8_8_4;} # Word/Register Direct (Rn):
SRC_B_AS: indexExtWord16_0_16s^"("^src_Indexed16_8_4^")" is src_Indexed16_8_4 & as=0x1 & bow=0x1 & AMASK ; indexExtWord16_0_16s {tmp:$(REG_SIZE) = (src_Indexed16_8_4 + indexExtWord16_0_16s) & AMASK; export *:1 tmp;}
SRC_B_AS: "@"^src_InDirect16_8_4 is src_InDirect16_8_4 & as=0x2 & bow=0x1 {export *:1 src_InDirect16_8_4;} # Word/Register Indirect (@Rn):
SRC_B_AS: "@"^src_InDirect16_8_4^"+" is src_InDirect16_8_4 & as=0x3 & bow=0x1 {export *:1 src_InDirect16_8_4;} # Word/Register Indirect Autoincrement (@Rn+):
SRC_B_AS: labelCalc is src16_8_4=0x0 & as=0x1 & bow=0x1 & AMASK ; indexExtWord16_0_16 [labelCalc = inst_start + 2 + indexExtWord16_0_16; ] {tmp:$(REG_SIZE) = labelCalc & AMASK;export *:1 tmp; } # Symbolic
SRC_B_AS: "#"^indexExtWord16_0_16 is src16_8_4=0x0 & as=0x3 & bow=0x1 ; indexExtWord16_0_16 {export *[const]:1 indexExtWord16_0_16;} # Immediate
SRC_B_AS: "&"^indexExtWord16_0_16 is src16_8_4=0x2 & as=0x1 & bow=0x1 ; indexExtWord16_0_16 {export *:1 indexExtWord16_0_16; } # Absolute
SRC_B_AS: "#4" is src16_8_4=0x2 & as=0x2 & bow=0x1 { export 4:1; } # Constant
SRC_B_AS: "#8" is src16_8_4=0x2 & as=0x3 & bow=0x1 { export 8:1; } # Constant
SRC_B_AS: "#0" is src16_8_4=0x3 & as=0x0 & bow=0x1 { export 0:1; } # Constant
SRC_B_AS: "#1" is src16_8_4=0x3 & as=0x1 & bow=0x1 { export 1:1; } # Constant
SRC_B_AS: "#2" is src16_8_4=0x3 & as=0x2 & bow=0x1 { export 2:1; } # Constant
SRC_B_AS: "#-1" is src16_8_4=0x3 & as=0x3 & bow=0x1 { export 0xff:1; } # Constant
#-----------------------------------------------
#
# DESTINATION (DEST)
#
#-----------------------------------------------
DEST_W_AD: DST16_0_4 is DST16_0_4 & ad=0x0 & bow=0x0
{export DST16_0_4;} # Word/Register Direct (Rn):
DEST_W_AD: indexExtWord16_0_16s^"("^dest_Indexed16_0_4^")" is dest_Indexed16_0_4 & ad=0x1 & bow=0x0 & AMASK ; indexExtWord16_0_16s
{tmp:$(REG_SIZE) = (dest_Indexed16_0_4 + indexExtWord16_0_16s) & AMASK; export *:2 tmp;}
#---Depends on SRC ---#
DEST_W_AD: indexExt2Word16_0_16s^"("^dest_Indexed16_0_4^")" is dest_Indexed16_0_4 & ad=0x1 & bow=0x0 & AMASK & as=0x1 & ((src16_8_4>=0x0 & src16_8_4<=0x2) | (src16_8_4>=0x4 & src16_8_4<=0xF)) ; indexExtWord16_0_16 ; indexExt2Word16_0_16s
{tmp:$(REG_SIZE) = (dest_Indexed16_0_4 + indexExt2Word16_0_16s) & AMASK; export *:2 tmp;}
DEST_W_AD: indexExt2Word16_0_16s^"("^dest_Indexed16_0_4^")" is dest_Indexed16_0_4 & ad=0x1 & bow=0x0 & AMASK & as=0x3 & src16_8_4=0x0 ; indexExtWord16_0_16 ; indexExt2Word16_0_16s
{tmp:$(REG_SIZE) = (dest_Indexed16_0_4 + indexExt2Word16_0_16s) & AMASK; export *:2 tmp;}
#---End of Depend ----#
DEST_W_AD: labelCalc is dest=0x0 & ad=0x1 & bow=0x0 & AMASK ; indexExtWord16_0_16s [labelCalc = inst_start + 2 + indexExtWord16_0_16s; ]
{tmp:$(REG_SIZE) = labelCalc & AMASK;export *:2 tmp; } # Symbolic
#---Depends on SRC ---#
DEST_W_AD: labelCalc is dest=0x0 & ad=0x1 & bow=0x0 & AMASK & as=0x1 & ((src16_8_4>=0x0 & src16_8_4<=0x2) | (src16_8_4>=0x4 & src16_8_4<=0xF)) ; indexExtWord16_0_16 ; indexExt2Word16_0_16s [labelCalc = inst_start + 4 + indexExt2Word16_0_16s; ]
{tmp:$(REG_SIZE) = labelCalc & AMASK;export *:2 tmp; } # Symbolic
DEST_W_AD: labelCalc is dest=0x0 & ad=0x1 & bow=0x0 & AMASK & as=0x3 & src16_8_4=0x0 ; indexExtWord16_0_16 ; indexExt2Word16_0_16s [labelCalc = inst_start + 4 + indexExt2Word16_0_16s; ]
{tmp:$(REG_SIZE) = labelCalc & AMASK;export *:2 tmp; } # Symbolic
#---End of Depend ----#
DEST_W_AD: "&"^indexExtWord16_0_16 is dest=0x2 & ad=0x1 & bow=0x0 ; indexExtWord16_0_16
{export *:2 indexExtWord16_0_16; } # Absolute
#---Depends on SRC ---#
DEST_W_AD: "&"^indexExt2Word16_0_16 is dest=0x2 & ad=0x1 & bow=0x0 & as=0x1 & ((src16_8_4>=0x0 & src16_8_4<=0x2) | (src16_8_4>=0x4 & src16_8_4<=0xF)) ; indexExtWord16_0_16 ; indexExt2Word16_0_16
{export *:2 indexExt2Word16_0_16; } # Absolute
DEST_W_AD: "&"^indexExt2Word16_0_16 is dest=0x2 & ad=0x1 & bow=0x0 & as=0x3 & src16_8_4=0x0 ; indexExtWord16_0_16 ; indexExt2Word16_0_16
{export *:2 indexExt2Word16_0_16; } # Absolute
#---End of Depend ----#
#-----------------------------------------------
DEST_B_AD: DST8_0_4 is DST8_0_4 & dest_Direct_lo & ad=0x0 & bow=0x1
{ export DST8_0_4; } # Word/Register Direct (Rn):
DEST_B_AD: indexExtWord16_0_16s^"("^dest_Indexed16_0_4^")" is dest_Indexed16_0_4 & ad=0x1 & bow=0x1 & AMASK ; indexExtWord16_0_16s
{ tmp:$(REG_SIZE) = (dest_Indexed16_0_4 + indexExtWord16_0_16s) & AMASK; export *:1 tmp;}
#---Depends on SRC ---#
DEST_B_AD: indexExt2Word16_0_16s^"("^dest_Indexed16_0_4^")" is dest_Indexed16_0_4 & ad=0x1 & bow=0x1 & AMASK & as=0x1 & ((src16_8_4>=0x0 & src16_8_4<=0x2) | (src16_8_4>=0x4 & src16_8_4<=0xF)) ; indexExtWord16_0_16 ; indexExt2Word16_0_16s
{ tmp:$(REG_SIZE) = (dest_Indexed16_0_4 + indexExt2Word16_0_16s) & AMASK; export *:1 tmp;}
DEST_B_AD: indexExt2Word16_0_16s^"("^dest_Indexed16_0_4^")" is dest_Indexed16_0_4 & ad=0x1 & bow=0x1 & AMASK & as=0x3 & src16_8_4=0x0 ; indexExtWord16_0_16 ; indexExt2Word16_0_16s
{ tmp:$(REG_SIZE) = (dest_Indexed16_0_4 + indexExt2Word16_0_16s) & AMASK; export *:1 tmp;}
#---End of Depend ----#
DEST_B_AD: labelCalc is dest=0x0 & ad=0x1 & bow=0x1 & AMASK ; indexExtWord16_0_16s [labelCalc = inst_start + 2 + indexExtWord16_0_16s; ]
{tmp:$(REG_SIZE) = labelCalc & AMASK; export *:1 tmp; } # Symbolic
#---Depends on SRC ---#
DEST_B_AD: labelCalc is dest=0x0 & ad=0x1 & bow=0x1 & AMASK & as=0x1 & ((src16_8_4>=0x0 & src16_8_4<=0x2) | (src16_8_4>=0x4 & src16_8_4<=0xF)) ; indexExtWord16_0_16 ; indexExt2Word16_0_16s [labelCalc = inst_start + 4 + indexExt2Word16_0_16s; ]
{tmp:$(REG_SIZE) = labelCalc & AMASK;export *:1 tmp; } # Symbolic
DEST_B_AD: labelCalc is dest=0x0 & ad=0x1 & bow=0x1 & AMASK & as=0x3 & src16_8_4=0x0 ; indexExtWord16_0_16 ; indexExt2Word16_0_16s [labelCalc = inst_start + 4 + indexExt2Word16_0_16s; ]
{tmp:$(REG_SIZE) = labelCalc & AMASK;export *:1 tmp; } # Symbolic
#---End of Depend ----#
DEST_B_AD: "&"^indexExtWord16_0_16 is dest=0x2 & ad=0x1 & bow=0x1 ; indexExtWord16_0_16
{export *:1 indexExtWord16_0_16; } # Absolute
#---Depends on SRC ---#
DEST_B_AD: "&"^indexExt2Word16_0_16 is dest=0x2 & ad=0x1 & bow=0x1 & as=0x1 & ((src16_8_4>=0x0 & src16_8_4<=0x2) | (src16_8_4>=0x4 & src16_8_4<=0xF)) ; indexExtWord16_0_16 ; indexExt2Word16_0_16
{export *:1 indexExt2Word16_0_16; } # Absolute
DEST_B_AD: "&"^indexExt2Word16_0_16 is dest=0x2 & ad=0x1 & bow=0x1 & as=0x3 & src16_8_4=0x0 ; indexExtWord16_0_16 ; indexExt2Word16_0_16
{export *:1 indexExt2Word16_0_16; } # Absolute
#---End of Depend ----#
# For handling constant operands in CALL and BR instructions.
DirectAddr: "#"^indexExtWord16_0_16 is indexExtWord16_0_16 {export *:$(REG_SIZE) indexExtWord16_0_16; }
tbl_bzero: is ad=0 & reg_Direct16_0_4 & dest_Direct_lo {ztmp:1 = dest_Direct_lo; reg_Direct16_0_4 = 0; dest_Direct_lo = ztmp; }
tbl_bzero: is epsilon {}
@if REG_SIZE == "4"
tbl_wzero: is ad=0 & reg_Direct16_0_4 & reg_Direct16_0_4W {ztmp:2 = reg_Direct16_0_4W; reg_Direct16_0_4 = 0; reg_Direct16_0_4W = ztmp; }
@endif
tbl_wzero: is epsilon {}
#
# Post Processing
# does correct increment of source register
# Also catches when PC is being stored to and does the correct branching
#
postRegIncrement: is as=0x3 & src16_8_4 & bow=0x0 & reg_InDirect16_0_4 { reg_InDirect16_0_4 = reg_InDirect16_0_4 + 2; }
postRegIncrement: is as=0x3 & src16_8_4 & bow=0x1 & reg_InDirect16_0_4 { reg_InDirect16_0_4 = reg_InDirect16_0_4 + 1; }
postRegIncrement: is as=0x3 & src16_8_4=1 & bow=0x1 & reg_InDirect16_0_4 { reg_InDirect16_0_4 = reg_InDirect16_0_4 + 2; }
postRegIncrement: is as=0x3 & src16_8_4=0 & bow=0x0 & reg_InDirect16_0_4 { } # PC is incremented by 2, but that is just to skip over the value
postRegIncrement: is as=0x3 & src16_8_4=0 & bow=0x1 & reg_InDirect16_0_4 { } # PC is incremented by 2, but that is just to skip over the value
postRegIncrement: is as=0x3 & src16_8_4=2 & bow=0x1 { }
postRegIncrement: is as=0x3 & src16_8_4=3 & bow=0x1 { }
postRegIncrement: is as=0x3 & src16_8_4=2 & bow=0x0 { }
postRegIncrement: is as=0x3 & src16_8_4=3 & bow=0x0 { }
postRegIncrement: is as & bow { }
# R2 and R3 are constant generators - post-increment not supported
postIncrement: is as=0x3 & ctx_haveext=0 & src16_8_4=2 & bow=0x0 & ctx_al=0
{ }
postIncrement: is as=0x3 & ctx_haveext=0 & src16_8_4=2 & bow=0x1 & ctx_al=0
{ }
postIncrement: is as=0x3 & ctx_haveext=0 & src16_8_4=3 & bow=0x0 & ctx_al=0
{ }
postIncrement: is as=0x3 & ctx_haveext=0 & src16_8_4=3 & bow=0x1 & ctx_al=0
{ }
postIncrement: is as=0x3 & src16_8_4=2 & bow=0x0
{ }
postIncrement: is as=0x3 & src16_8_4=2 & bow=0x1
{ }
postIncrement: is as=0x3 & src16_8_4=3 & bow=0x0
{ }
postIncrement: is as=0x3 & src16_8_4=3 & bow=0x1
{ }
postIncrement: is as=0x3 & src16_8_4=0 & bow=0x1 & src_InDirect16_8_4
{ } # PC is incremented by 2, but that is just to skip over the value
postIncrement: is as=0x3 & src16_8_4=0 & bow=0x0 & src_InDirect16_8_4
{ } # PC is incremented by 2, but that is just to skip over the value
postIncrement: is as=0x3 & src16_8_4 & bow=0x0 & src_InDirect16_8_4
{ src_InDirect16_8_4 = src_InDirect16_8_4 + 2; }
postIncrement: is as=0x3 & src16_8_4 & bow=0x1 & ctx_al=0 & src_InDirect16_8_4
{ src_InDirect16_8_4 = src_InDirect16_8_4 + 4; }
postIncrement: is as=0x3 & src16_8_4=1 & bow=0x1 & ctx_al=0 & src_InDirect16_8_4
{ src_InDirect16_8_4 = src_InDirect16_8_4 + 4; }
postIncrement: is as=0x3 & src16_8_4 & bow=0x1 & ctx_al=1 & src_InDirect16_8_4
{ src_InDirect16_8_4 = src_InDirect16_8_4 + 1; }
postIncrement: is as=0x3 & src16_8_4=1 & bow=0x1 & ctx_al=1 & src_InDirect16_8_4
{ src_InDirect16_8_4 = src_InDirect16_8_4 + 2; }
postIncrement: is as=0x3 & ctx_haveext=0 & src16_8_4 & bow=0x1 & ctx_al=0 & src_InDirect16_8_4
{ src_InDirect16_8_4 = src_InDirect16_8_4 + 1; }
postIncrement: is as=0x3 & ctx_haveext=0 & src16_8_4=1 & bow=0x1 & ctx_al=0 & src_InDirect16_8_4
{ src_InDirect16_8_4 = src_InDirect16_8_4 + 2; }
postIncrement: is as & src16_8_4 & bow
{ }
#
# Zero Extends if the store is byte oriented, and a register is being stored to
zeroExtend: is dest_Direct_lo & dest_Direct16_0_4
{ dest_Direct16_0_4 = zext(dest_Direct_lo); }
#
# Post processing when destination is the PC
#
postIncrementStore: is postIncrement & ad=0x0 & src_InDirect16_8_4 & as=0x3 & src16_8_4=1 & dest_Direct16_0_4=0x0 & bow=0x1 & ctx_al=1 & zeroExtend
{ build zeroExtend; build postIncrement; return [PC]; }
postIncrementStore: is postIncrement & ad=0x0 & dest_Direct16_0_4=0x0 & bow=0x1 & ctx_al=1 & zeroExtend
{ build zeroExtend; build postIncrement; goto [PC];}
postIncrementStore: is postIncrement & ad=0x0 & bow=0x1 & ctx_al=1 & zeroExtend
{ build zeroExtend; build postIncrement; }
postIncrementStore: is postIncrement & ctx_haveext=0 & ad=0x0 & src_InDirect16_8_4 & as=0x3 & src16_8_4=1 & dest_Direct16_0_4=0x0 & bow=0x1 & zeroExtend
{ build zeroExtend; build postIncrement; return [PC]; }
postIncrementStore: is postIncrement & ctx_haveext=0 & ad=0x0 & dest_Direct16_0_4=0x0 & bow=0x1 & zeroExtend
{ build zeroExtend; build postIncrement; goto [PC];}
postIncrementStore: is postIncrement & ctx_haveext=0 & ad=0x0 & bow=0x1 & zeroExtend
{ build zeroExtend; build postIncrement; }
postIncrementStore: is postIncrement & ad=0x0 & src_InDirect16_8_4 & as=0x3 & src16_8_4=1 & dest_Direct16_0_4=0x0
{ build postIncrement; return [PC]; }
postIncrementStore: is postIncrement & ad=0x0 & dest_Direct16_0_4=0x0
{ build postIncrement; goto [PC];}
postIncrementStore: is postIncrement & ad & bow
{ build postIncrement; }
#-----------------------------------------------
#
# JUMP CONDITION (JCND)
#
#-----------------------------------------------
JCND: "NE" is condition=0x0 {cndTst:1 = !$(ZERO); export cndTst;} # Not Equal/Zero (cleared)
JCND: "EQ" is condition=0x1 {cndTst:1 = $(ZERO); export cndTst;} # Equal/Zero (set)
JCND: "NC" is condition=0x2 {cndTst:1 = !$(CARRY); export cndTst;} # No Carry/Lower (cleared)
JCND: "C" is condition=0x3 {cndTst:1 = $(CARRY); export cndTst;} # Carry/Higher or same (set)
JCND: "N" is condition=0x4 {cndTst:1 = $(SIGN); export cndTst;} # Negative (set)
JCND: "GE" is condition=0x5 {cndTst:1 = ($(SIGN) == $(OVERFLOW)); export cndTst;} # Greater or equal (>=)
JCND: "L" is condition=0x6 {cndTst:1 = ($(SIGN) != $(OVERFLOW)); export cndTst;} # Less (<)
JCND: "MP" is condition=0x7 {cndTst:1 = 0x1; export cndTst;} # Unconditional
#-----------------------------------------------
#
# 10 BIT OFFSET
#
#-----------------------------------------------
OFFSET_10BIT: offset10 is off16 [offset10 = inst_start + 2 + off16 * 2; ]
{ export *:2 offset10;}
###################################################################################
#
# Single-operand arithmetic
#
# ------------------------------------------------------------------------------
# | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
# ------------------------------------------------------------------------------
# | 0 | 0 | 0 | 1 | 0 | 0 | opcode | B/W | As | register |
# ------------------------------------------------------------------------------
###################################################################################
###################################################################################
#
# RRC: Rotate right through carry
# ------------------------------------------------------------------------------
# | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
# ------------------------------------------------------------------------------
# | 0 | 0 | 0 | 1 | 0 | 0 | 000 | B/W | As | register |
:RRC^".W" REG_W_AS_DEST is ctx_haveext=0 & (op16_12_4=0x1 & op16_8_4=0x0 & op16_7_1=0x0 & bow=0x0 & tbl_wzero & postRegIncrement) ... & REG_W_AS_DEST {
# Operation Flags...
$(OVERFLOW) = ((REG_W_AS_DEST != 0x0) && ($(CARRY) == 0x1)); # V Flag
# Operation...
tmp:1 = $(CARRY);
$(CARRY) = REG_W_AS_DEST[0,1];
REG_W_AS_DEST = ((zext(tmp) << 0xF) | (REG_W_AS_DEST >> 0x1));
build tbl_wzero;
# Result Flags...
$(SIGN) = (REG_W_AS_DEST s< 0x0); # S Flag
$(ZERO) = (REG_W_AS_DEST == 0x0); # Z Flag
build postRegIncrement;
}
:RRC^".B" REG_B_AS_DEST is ctx_haveext=0 & (op16_12_4=0x1 & op16_8_4=0x0 & op16_7_1=0x0 & bow=0x1 & tbl_bzero & postRegIncrement) ... & REG_B_AS_DEST {
# Operation Flags...
$(OVERFLOW) = ((REG_B_AS_DEST != 0x0) && ($(CARRY) == 0x1)); # V Flag
# Operation...
tmp:1 = $(CARRY);
$(CARRY) = (REG_B_AS_DEST & 0x1);
REG_B_AS_DEST = ((tmp << 0x7) | (REG_B_AS_DEST >> 0x1));
build tbl_bzero;
# Result Flags...
$(SIGN) = (REG_B_AS_DEST s< 0x0); # S Flag
$(ZERO) = (REG_B_AS_DEST == 0x0); # Z Flag
build postRegIncrement;
}
###################################################################################
#
# SWPB: Swap bytes
# ------------------------------------------------------------------------------
# | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
# ------------------------------------------------------------------------------
# | 0 | 0 | 0 | 1 | 0 | 0 | 001 | 0 | As | register |
:SWPB REG_W_AS_DEST is ctx_haveext=0 & (op16_12_4=0x1 & op16_8_4=0x0 & op16_7_1=0x1 & bow=0x0 & tbl_wzero & postRegIncrement) ... & REG_W_AS_DEST {
lowByte:1 = REG_W_AS_DEST[0,8];
highByte:1 = REG_W_AS_DEST[8,8];
REG_W_AS_DEST = (((zext(lowByte)) << 0x8) | zext(highByte));
build tbl_wzero;
#Status bits are not affected
build postRegIncrement;
}
###################################################################################
#
# RRA: Rotate right arithmetic
# ------------------------------------------------------------------------------
# | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
# ------------------------------------------------------------------------------
# | 0 | 0 | 0 | 1 | 0 | 0 | 010 | B/W | As | register |
:RRA^".W" REG_W_AS_DEST is ctx_haveext=0 & (op16_12_4=0x1 & op16_8_4=0x1 & op16_7_1=0x0 & bow=0x0 & tbl_wzero & postRegIncrement) ... & REG_W_AS_DEST {
# Operation Flags...
$(OVERFLOW) = 0x0; # V Flag (reset)
# Operation...
$(CARRY) = REG_W_AS_DEST[0,1];
MSB:2 = REG_W_AS_DEST >> 0xF;
REG_W_AS_DEST = ((MSB << 0xF) | (REG_W_AS_DEST >> 0x1));
build tbl_wzero;
# Result Flags...
$(SIGN) = (REG_W_AS_DEST s< 0x0); # S Flag
$(ZERO) = (REG_W_AS_DEST == 0x0); # Z Flag
build postRegIncrement;
}
:RRA^".B" REG_B_AS_DEST is ctx_haveext=0 & (op16_12_4=0x1 & op16_8_4=0x1 & op16_7_1=0x0 & bow=0x1 & tbl_bzero & postRegIncrement) ... & REG_B_AS_DEST {
# Operation Flags...
$(OVERFLOW) = 0x0; # V Flag (reset)
# Operation...
$(CARRY) = (REG_B_AS_DEST & 0x1);
MSB:1 = REG_B_AS_DEST >> 0x7;
REG_B_AS_DEST = ((MSB << 0x7) | (REG_B_AS_DEST >> 0x1));
build tbl_bzero;
# Result Flags...
$(SIGN) = (REG_B_AS_DEST s< 0x0); # S Flag
$(ZERO) = (REG_B_AS_DEST == 0x0); # Z Flag
build postRegIncrement;
}
###################################################################################
#
# SXT: Sign extend byte to word
# ------------------------------------------------------------------------------
# | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
# ------------------------------------------------------------------------------
# | 0 | 0 | 0 | 1 | 0 | 0 | 011 | 0 | As | register |
:SXT REG_W_AS_DEST is ctx_haveext=0 & (op16_12_4=0x1 & op16_8_4=0x1 & op16_7_1=0x1 & bow=0x0 & tbl_wzero & postRegIncrement) ... & REG_W_AS_DEST {
# Operation Flags...
$(OVERFLOW) = 0x0; # V Flag
# Operation...
byteVal:1 = REG_W_AS_DEST[0,8];
REG_W_AS_DEST = sext(byteVal);
build tbl_wzero;
# Result Flags...
$(SIGN) = (REG_W_AS_DEST s< 0x0); # S Flag
$(ZERO) = (REG_W_AS_DEST == 0x0); # Z Flag
$(CARRY) = (REG_W_AS_DEST != 0x0); # C Flag
build postRegIncrement;
}
###################################################################################
#
# PUSH: Push value onto stack
# ------------------------------------------------------------------------------
# | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
# ------------------------------------------------------------------------------
# | 0 | 0 | 0 | 1 | 0 | 0 | 100 | B/W | As | register |
:PUSH^".W" REG_W_AS is ctx_haveext=0 & (op16_12_4=0x1 & op16_8_4=0x2 & op16_7_1=0x0 & bow=0x0 & postRegIncrement) ... & REG_W_AS {
SP = SP - 0x2;
*:2 SP = REG_W_AS;
#Status bits are not affected
build postRegIncrement;
}
:PUSH^".B" REG_B_AS is ctx_haveext=0 & (op16_12_4=0x1 & op16_8_4=0x2 & op16_7_1=0x0 & bow=0x1 & postRegIncrement) ... & REG_B_AS {
SP = SP - 0x2;
*:1 SP = REG_B_AS;
#Status bits are not affected
build postRegIncrement;
}
###################################################################################
#
# CALL: Subroutine call; push PC and move source to PC
# ------------------------------------------------------------------------------
# | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
# ------------------------------------------------------------------------------
# | 0 | 0 | 0 | 1 | 0 | 0 | 101 | 0 | As | register |
:CALL REG_W_AS is ctx_haveext=0 & (op16_12_4=0x1 & op16_8_4=0x2 & op16_7_1=0x1 & bow=0x0 & postRegIncrement) ... & REG_W_AS {
SP = SP - 0x2;
*:2 SP = inst_next;
PC = zext(REG_W_AS);
build postRegIncrement;
call [PC];
#Status bits are not affected
}
:CALL DirectAddr is ctx_haveext=0 & (op16_12_4=0x1 & op16_8_4=0x2 & op16_7_1=0x1 & reg16_0_4=0x0 & as=0x3 & bow=0x0 & postRegIncrement); DirectAddr {
SP = SP - 0x2;
*:2 SP = inst_next;
PC = &DirectAddr;
build postRegIncrement;
call DirectAddr;
#Status bits are not affected
}
###################################################################################
#
# RETI: Return from interrupt; pop SR then pop PC
# ------------------------------------------------------------------------------
# | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
# ------------------------------------------------------------------------------
# | 0 | 0 | 0 | 1 | 0 | 0 | 110 | 0 | 00 | 0000 |
:RETI is ctx_haveext=0 & op16_12_4=0x1 & op16_8_4=0x3 & op16_7_1=0x0 & as=0x0 & bow=0x0 & op16_0_4=0x0 & op16_4_4=0x0 {
@if REG_SIZE == "2"
SR = *:2 SP;
SP = SP + 0x2;
PC = *:2 SP;
@else
tmp:$(REG_SIZE) = zext(*:2 SP);
SR = zext(tmp[0,12]);
SP = SP + 0x2;
PC = zext(*:2 SP) | ((tmp & 0xF000) << 4);
@endif
SP = SP + 0x2;
return [PC];
#Status bits are restored from system stack
}
###################################################################################
#
# Conditional jump; PC = PC + 2*offset
#
# ------------------------------------------------------------------------------
# | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
# ------------------------------------------------------------------------------
# | 0 | 0 | 1 | condition | 10-bit signed offset |
# ------------------------------------------------------------------------------
###################################################################################
###################################################################################
#
# J^JumpCondition 10-bit_signed_offset
# ------------------------------------------------------------------------------
# | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
# ------------------------------------------------------------------------------
# | 0 | 0 | 1 | condition | 10-bit signed offset |
:J^JCND OFFSET_10BIT is ctx_haveext=0 & op16_13_3=0x1 & JCND & OFFSET_10BIT {
if (JCND) goto OFFSET_10BIT;
#Status bits are not affected
}
:JMP OFFSET_10BIT is ctx_haveext=0 & op16_13_3=0x1 & condition=0x7 & OFFSET_10BIT {
goto OFFSET_10BIT;
#Status bits are not affected
}
###################################################################################
#
# Two-operand arithmetic
#
# ------------------------------------------------------------------------------
# | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
# ------------------------------------------------------------------------------
# | opcode | source | Ad | B/W | As | destination |
# ------------------------------------------------------------------------------
###################################################################################
###################################################################################
#
# MOV: Move source to destination
# ------------------------------------------------------------------------------
# | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
# ------------------------------------------------------------------------------
# | 0 1 0 0 | source | Ad | B/W | As | destination |
#-----------------------
# Emulated instructions
#-----------------------
# Branch
:BR SRC_W_AS is ctx_haveext=0 & (op16_12_4=0x4 & bow=0x0 & ad=0x0 & dest_Direct16_0_4=0x0) ... & SRC_W_AS ... {
PC = zext(SRC_W_AS);
goto [PC];
#Status bits are not affected
}
# Branch to an immediate value
:BR DirectAddr is ctx_haveext=0 & (op16_12_4=0x4 & bow=0x0 & ad=0x0 & dest_Direct16_0_4=0x0 & src_Direct16_8_4=0x0 & as=0x3); DirectAddr {
PC = &DirectAddr;
goto DirectAddr;
#Status bits are not affected
}
# No operation
:NOP is ctx_haveext=0 & op16_12_4=0x4 & bow=0x0 & ad=0x0 & as=0x0 & dest_Direct16_0_4=0x3 & src_Direct16_8_4=0x3 & postIncrement {
#Status bits are not affected
build postIncrement;
}
# Pop word from stack
:POP^".W" DEST_W_AD is ctx_haveext=0 & (op16_12_4=0x4 & bow=0x0 & (ad=0x1 | dest_Direct16_0_4) & as=0x3 & src_Direct16_8_4=0x1 & tbl_wzero) ... & DEST_W_AD ... {
DEST_W_AD = *:2 SP;
build tbl_wzero;
SP = SP + 0x2;
#Status bits are not affected
}
# Pop byte from stack
:POP^".B" DEST_B_AD is ctx_haveext=0 & (op16_12_4=0x4 & bow=0x1 & (ad=0x1 | dest_Direct16_0_4) & as=0x3 & src_Direct16_8_4=0x1 & tbl_bzero) ... & DEST_B_AD ... {
DEST_B_AD = *:1 SP;
build tbl_bzero;
SP = SP + 0x2;
#Status bits are not affected
}
# Return from subroutine
:RET is ctx_haveext=0 & op16_12_4=0x4 & bow=0x0 & ad=0x0 & as=0x3 & dest_Direct16_0_4=0x0 & src_Direct16_8_4=0x1 {
PC = zext(*:2 SP);
SP = SP + 0x2;
return [PC];
#Status bits are not affected
}
#------------------
# SRC Word
#------------------
:MOV^".W" SRC_W_AS, DEST_W_AD is ctx_haveext=0 & (op16_12_4=0x4 & bow=0x0 & tbl_wzero & postIncrementStore) ... & SRC_W_AS ... & DEST_W_AD ... {
DEST_W_AD = SRC_W_AS;
build tbl_wzero;
#Status bits are not affected
build postIncrementStore;
}
#------------------
# SRC Byte
#------------------
:MOV^".B" SRC_B_AS, DEST_B_AD is ctx_haveext=0 & (op16_12_4=0x4 & bow=0x1 & tbl_bzero & postIncrementStore) ... & SRC_B_AS ... & DEST_B_AD ... {
DEST_B_AD = SRC_B_AS;
build tbl_bzero;
#Status bits are not affected
build postIncrementStore;
}
###################################################################################
#
# ADD: Add source to destination
# ------------------------------------------------------------------------------
# | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
# ------------------------------------------------------------------------------
# | 0 1 0 1 | source | Ad | B/W | As | destination |
#-----------------------
# Emulated instructions
#-----------------------
# Increment word
:INC^".W" DEST_W_AD is ctx_haveext=0 & (op16_12_4=0x5 & as=0x1 & src_Direct16_8_4=0x3 & bow=0x0 & tbl_wzero & postIncrementStore) ... & DEST_W_AD ... {
# Operation Flags...
$(CARRY) = carry(DEST_W_AD,1); # C Flag
$(OVERFLOW) = scarry(DEST_W_AD,1); # V Flag
# Operation...
DEST_W_AD = DEST_W_AD + 0x1;
build tbl_wzero;
# Result Flags...
$(SIGN) = (DEST_W_AD s< 0x0); # S Flag
$(ZERO) = (DEST_W_AD == 0x0); # Z Flag
build postIncrementStore;
}
# Increment byte
:INC^".B" DEST_B_AD is ctx_haveext=0 & (op16_12_4=0x5 & as=0x1 & src_Direct16_8_4=0x3 & bow=0x1 & tbl_bzero & postIncrementStore) ... & DEST_B_AD ... {
# Operation Flags...
$(CARRY) = carry(DEST_B_AD,1); # C Flag
$(OVERFLOW) = scarry(DEST_B_AD,1); # V Flag
# Operation...
DEST_B_AD = DEST_B_AD + 0x1;
build tbl_bzero;
# Result Flags...
$(SIGN) = (DEST_B_AD s< 0x0); # S Flag
$(ZERO) = (DEST_B_AD == 0x0); # Z Flag
build postIncrementStore;
}
# Double increment word
:INCD^".W" DEST_W_AD is ctx_haveext=0 & (op16_12_4=0x5 & as=0x2 & src_Direct16_8_4=0x3 & bow=0x0 & tbl_wzero & postIncrementStore) ... & DEST_W_AD ... {
# Operation Flags...
$(CARRY) = carry(DEST_W_AD,2); # C Flag
$(OVERFLOW) = scarry(DEST_W_AD,2); # V Flag
# Operation...
DEST_W_AD = DEST_W_AD + 0x2;
build tbl_wzero;
# Result Flags...
$(SIGN) = (DEST_W_AD s< 0x0); # S Flag
$(ZERO) = (DEST_W_AD == 0x0); # Z Flag
build postIncrementStore;
}
# Double increment byte
:INCD^".B" DEST_B_AD is ctx_haveext=0 & (op16_12_4=0x5 & as=0x2 & src_Direct16_8_4=0x3 & bow=0x1 & tbl_bzero & postIncrementStore) ... & DEST_B_AD ... {
# Operation Flags...
$(CARRY) = carry(DEST_B_AD,2); # C Flag
$(OVERFLOW) = scarry(DEST_B_AD,2); # V Flag
# Operation...
DEST_B_AD = DEST_B_AD + 0x2;
build tbl_bzero;
# Result Flags...
$(SIGN) = (DEST_B_AD s< 0x0); # S Flag
$(ZERO) = (DEST_B_AD == 0x0); # Z Flag
build postIncrementStore;
}
# Rotate left arithmetic (left shift once) word
:RLA^".W" DEST_W_AD is ctx_haveext=0 & (op16_12_4=0x5 & as=0x0 & ad=0x0 & src_Direct16_8_4=dest_Direct16_0_4 & bow=0x0 & tbl_wzero & postIncrementStore) ... & DEST_W_AD ... {
# Operation Flags...
$(CARRY) = carry(DEST_W_AD, DEST_W_AD); # C Flag
$(OVERFLOW) = scarry(DEST_W_AD, DEST_W_AD); # V Flag
# Operation...
DEST_W_AD = DEST_W_AD + DEST_W_AD;
build tbl_wzero;
# Result Flags...
$(SIGN) = (DEST_W_AD s< 0x0); # S Flag
$(ZERO) = (DEST_W_AD == 0x0); # Z Flag
build postIncrementStore;
}
# Rotate left arithmetic (left shift once) byte
:RLA^".B" DEST_B_AD is ctx_haveext=0 & (op16_12_4=0x5 & as=0x0 & ad=0x0 & src_Direct16_8_4=dest_Direct16_0_4 & bow=0x1 & tbl_bzero & postIncrementStore) ... & DEST_B_AD ... {
# Operation Flags...
$(CARRY) = carry(DEST_B_AD, DEST_B_AD); # C Flag
$(OVERFLOW) = scarry(DEST_B_AD, DEST_B_AD); # V Flag
# Operation...
DEST_B_AD = DEST_B_AD + DEST_B_AD;
build tbl_bzero;
# Result Flags...
$(SIGN) = (DEST_B_AD s< 0x0); # S Flag
$(ZERO) = (DEST_B_AD == 0x0); # Z Flag
build postIncrementStore;
}
#------------------
# 16 bit SRC Word
#------------------
:ADD^".W" SRC_W_AS, DEST_W_AD is ctx_haveext=0 & (op16_12_4=0x5 & bow=0x0 & tbl_wzero & postIncrementStore) ... & SRC_W_AS ... & DEST_W_AD ... {
# Operation Flags...
$(CARRY) = carry(SRC_W_AS, DEST_W_AD); # C Flag
$(OVERFLOW) = scarry(SRC_W_AS, DEST_W_AD); # V Flag
# Operation...
DEST_W_AD = SRC_W_AS + DEST_W_AD;
build tbl_wzero;
# Result Flags...
$(SIGN) = (DEST_W_AD s< 0x0); # S Flag
$(ZERO) = (DEST_W_AD == 0x0); # Z Flag
build postIncrementStore;
}
#------------------
# 16 bit SRC Byte
#------------------
:ADD^".B" SRC_B_AS, DEST_B_AD is ctx_haveext=0 & (op16_12_4=0x5 & bow=0x1 & tbl_bzero & postIncrementStore) ... & SRC_B_AS ... & DEST_B_AD ... {
# Operation Flags...
$(CARRY) = carry(SRC_B_AS, DEST_B_AD); # C Flag
$(OVERFLOW) = scarry(SRC_B_AS, DEST_B_AD); # V Flag
# Operation...
DEST_B_AD = SRC_B_AS + DEST_B_AD;
build tbl_bzero;
# Result Flags...
$(SIGN) = (DEST_B_AD s< 0x0); # S Flag
$(ZERO) = (DEST_B_AD == 0x0); # Z Flag
build postIncrementStore;
}
###################################################################################
#
# ADDC: Add source and carry to destination
# ------------------------------------------------------------------------------
# | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
# ------------------------------------------------------------------------------
# | 0 1 1 0 | source | Ad | B/W | As | destination |
#-----------------------
# Emulated instructions
#-----------------------
# Add carry to word
:ADC^".W" DEST_W_AD is ctx_haveext=0 & (op16_12_4=0x6 & as=0x0 & src_Direct16_8_4=0x3 & bow=0x0 & tbl_wzero & postIncrementStore) ... & DEST_W_AD ... {
# Operation Flags...
tmp_carry:1 = carry(DEST_W_AD,zext($(CARRY))); #C Flag
$(OVERFLOW) = scarry(DEST_W_AD, zext($(CARRY))); #V Flag
# Operation...
DEST_W_AD = DEST_W_AD + zext($(CARRY));
build tbl_wzero;
# Result Flags...
$(CARRY) = tmp_carry;
$(SIGN) = (DEST_W_AD s< 0x0); # S Flag
$(ZERO) = (DEST_W_AD == 0x0); # Z Flag
build postIncrementStore;
}
# Add carry to byte
:ADC^".B" DEST_B_AD is ctx_haveext=0 & (op16_12_4=0x6 & as=0x0 & src_Direct16_8_4=0x3 & bow=0x1 & tbl_bzero & postIncrementStore) ... & DEST_B_AD ... {
# Operation Flags...
tmp_carry:1 = carry(DEST_B_AD,$(CARRY)); #C Flag
$(OVERFLOW) = scarry(DEST_B_AD,$(CARRY)); #V Flag
# Operation...