-
Notifications
You must be signed in to change notification settings - Fork 30
/
Copy pathInstruction_formats
174 lines (134 loc) · 7.66 KB
/
Instruction_formats
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
Condition codes (Cond):
D = digit carry (for decimal math - we ignore this ;-)
N = negative (high bit set)
V = overflow
C = carry
Z = zero
Note also: This is one of the few (and the proud?) architectures that
implements borrow in the "natural" way - that is, borrow = not carry.
Opcode bits Name Cond Notes
=================== ======= ===== =====
0000 0000 0000 0000 nop
0000 0000 0000 0011 sleep
0000 0000 0000 0100 clrwdt clear watchdog timer
0000 0000 0000 0101 push inc STKPTR; TOS U:H:L = pc + 2
0000 0000 0000 0110 pop dec STKPTR
0000 0000 0000 0111 daw C decimal adjust w
0000 0000 0000 1000 tblrd* read program memory
0000 0000 0000 1001 tblrd*+ read program memory, post incr
0000 0000 0000 1010 tblrd*- read program memory, post decr
0000 0000 0000 1011 tblrd+* read program memory, pre incr
0000 0000 0000 1100 tblwt* write program memory
0000 0000 0000 1101 tblwt*+ write program memory, post incr
0000 0000 0000 1110 tblwt*- write program memory, post decr
0000 0000 0000 1111 tblwt+* write program memory, pre incr
( s=1 means restore W, STATUS, BSR from shadow regs.)
0000 0000 0001 000s retfie return from interrupt and enable
0000 0000 0001 001s return subroutine return
0000 0000 0110 ssss movffl like movff, but with 14-bit offsets
ssss = src<13:10>
1111 ssss ssss ssdd ssss ssss ss = src<9:0>; dd = dst<13:12>
1111 dddd dddd dddd dddd dddd dddd = dst<11:0>
Only on chips with #bsr-bits >= 6
0000 0000 1111 1111 reset DNVCZ
0000 0001 0000 kkkk movlb bank = k ( 4-bit bsr)
0000 0001 00kk kkkk movlb bank = k ( 6-bit bsr)
0000 001a ffff ffff mulwf PRODH:PRODL = w * f
0000 01da ffff ffff decf DNVCZ f/w = f - 1
0000 1000 kkkk kkkk sublw DNVCZ w = k - w ( !!) ( rsub? rsb?)
0000 1001 kkkk kkkk iorlw NZ w = k or w
0000 1010 kkkk kkkk xorlw NZ w = k xor w
0000 1011 kkkk kkkk andlw NZ w = k and w
0000 1100 kkkk kkkk retlw return with w = k
0000 1101 kkkk kkkk mullw PRODH:PRODL = k * w
0000 1110 kkkk kkkk movlw w = k
0000 1111 kkkk kkkk addlw DNVCZ w = k + w
( d=0 means dest is W; d=1 means dest is F
a=0 means "access bank" - BSF ignored - but see XINST notes below:
00 - 5f --> 000 - 05f -- these addresses are chip-dependent
60 - ff --> f60 - fff -- but the same idea applies to all
a=1 means use BSF bank register:
addr = bbbb ffff ffff, where bbbb is BSF reg
ffff ffff is from instruction)
( NOTE: comf is a 2op, but negf is a 1op!)
0001 00da ffff ffff iorwf NZ f/w = w or f
0001 01da ffff ffff andwf NZ f/w = w and f
0001 10da ffff ffff xorwf NZ f/w = w xor f
0001 11da ffff ffff comf NZ f/w = ~f
0010 00da ffff ffff addwfc DNVCZ f/w = w + f + C
0010 01da ffff ffff addwf DNVCZ f/w = w + f
0010 10da ffff ffff incf DNVCZ f/w = f + 1
0010 11da ffff ffff decfsz f/w = f - 1, skip if zero
0011 00da ffff ffff rrcf NCZ f/w = f rotate r thru C
0011 01da ffff ffff rlcf NCZ f/w = f rotate l thru C
0011 10da ffff ffff swapf f/w = swap_nybbles(f)
0011 11da ffff ffff incfsz f/w = f + 1, skip if zero
0100 00da ffff ffff rrncf NZ f/w = f rotate r
0100 01da ffff ffff rlncf NZ f/w = f rotate l
0100 10da ffff ffff infsnz f/w = inc f, skip nz
0100 11da ffff ffff dcfsnz f/w = dec f, skip nz
0101 00da ffff ffff movf NZ f/w = f ( affects N, Z) ( tst?)
0101 01da ffff ffff subfwb DNVCZ f/w = w - f - borrow (~C)
0101 10da ffff ffff subwfb DNVCZ f/w = f - w - borrow
0101 11da ffff ffff subwf DNVCZ f/w = f - w
0110 000a ffff ffff cpfslt f - w, skip if lt ( unsigned)
0110 001a ffff ffff cpfseq f - w, skip if eq
0110 010a ffff ffff cpfsgt f - w, skip if gt ( unsigned)
0110 011a ffff ffff tstfsz test f, skip if 0
0110 100a ffff ffff setf f = ff ( no status chg)
0110 101a ffff ffff clrf Z f = 0 ( Z = 1)
0110 110a ffff ffff negf DNVCZ f = -f
0110 111a ffff ffff movwf f = w ( no status chg) ( store?)
0111 bbba ffff ffff btg bit toggle f
1000 bbba ffff ffff bsf bit set f
1001 bbba ffff ffff bcf bit clr f
1010 bbba ffff ffff btfss bit test, skip set
1011 bbba ffff ffff btfsc bit test, skip clr
1100 ffff ffff ffff movff + 1111 ffff ffff ffff
first word has source offset; second word has dest
( pc = pc + 2 + 2n)
1101 0nnn nnnn nnnn bra branch relative
1101 1nnn nnnn nnnn rcall call relative
( pc = pc + 2 + 2n)
1110 0000 nnnn nnnn bz br if zero
1110 0001 nnnn nnnn bnz br if not zero
1110 0010 nnnn nnnn bc br if carry ( bcs, bhs, u>= )
1110 0011 nnnn nnnn bnc br if no carry ( bcc, blo, u< )
( NOTE: To do proper signed branches we have to _combine_ tests of N and V!!)
1110 0100 nnnn nnnn bov br if overflow ( bv?)
1110 0101 nnnn nnnn bnov br if no overflow ( bnv?)
1110 0110 nnnn nnnn bn br if negative ( bmi?)
1110 0111 nnnn nnnn bnn br if not negative! ( bpl?)
1110 10xx *unimplemented* ( extended instructions)
( For call and goto, the low 8 bits are in the first instruction word; the high
12 bits follow in the extension word.
For lfsr, the high 4 bits are in the first instruction word; the low 8 (or
10 for 6 bit bsr chips) follow in the extension word.)
( s=1 means save W, STATUS, BSR in shadow regs.)
1110 110s kkkk kkkk call ( long) + 1111 kkkk kkkk kkkk
( low) ( high)
1110 1110 00ff kkkk lfsr + 1111 0000 kkkk kkkk ( load pointer; 4-bit bsr)
1110 1110 00ff kkkk lfsr + 1111 00kk kkkk kkkk ( load pointer; 6-bit bsr)
( high) ( low)
1110 1111 kkkk kkkk goto ( long) + 1111 kkkk kkkk kkkk
( low) ( high)
1111 kkkk kkkk kkkk nop useful to extend an instruction with address bits
( If XINST is set in config regs, enable extended instructions and enable
indexed addressing with literal offset. Access mode changes in this case.
Instead of addresses 0 to 5f being _absolute_ addresses in the chip's RAM, they
become _offsets_ to FSR2. So in order have access to absolute RAM addresses it
is necessary to use banked mode - a=1 - and to set the bank register
accordingly.)
( Here are the extended instructions:)
0000 0000 0001 0100 callw push pc + 2; pcl = w, pch = pclath, pcu = pclatu
1110 1000 ffkk kkkk addfsr add literal to fsr 0, 1, or 2
1110 1000 11kk kkkk addulnk add literal to fsr 2 and return
1110 1001 ffkk kkkk subfsr subtract literal from fsr 0, 1, or 2
1110 1001 11kk kkkk subulnk subtract literal from fsr 2 and return
1110 1010 kkkk kkkk pushl store lit at FSR2; dec FSR2 ( ie, post-decrement)
( In movsf and movss, the z offsets are added to FSR2)
1110 1011 0zzz zzzz movsf + 1111 ffff ffff ffff move stack to f
1110 1011 1zzz zzzz movss + 1111 xxxx xzzz zzzz move stack to stack
( On chips with 6-bit BSRs, there is also the following:)
0000 0000 0000 0010 movsfl + 1111 xxxz zzzz zzff src z offset; high 2 bits of dest f
+ 1111 ffff ffff ffff low 12 of dest f