Menu

[r4191]: / trunk / isa / avr.isa  Maximize  Restore  History

Download this file

281 lines (238 with data), 9.0 kB

  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
;
; $Id$
;
; An instruction set description for Atmel AVR(TM) 8 bit CPUs.
;
; * Most instructions are 16 bit wide, except a few that use an
; additional 16-bit offset field.
; * There are 32 general purpose registers which are 8-bit wide.
; Three pairs of registers are used for 16bit memory addressing:
; X (r27:r26), Y (r29:r28), and Z (r31:r30).
; * Some instructions operate on limited subsets of these registers:
; - The 'movw' instruction operates on register pairs.
; - Some instructions only operate on subsets of the register file.
arch avr
cpus
core = [ AT90S1200 ATtiny11 ATtiny12 ATtiny15 ATtiny28 ]
core8k = core ++ [ AT90S2313 AT90S2323 ATtiny22 AT90S2333
AT90S2343 AT90S4414 AT90S4433 AT90S4434 AT90S8515
AT90C8534 AT90S8535 ATtiny26 ATmega8515 ]
core128k = core8k ++ [ ATmega103 ATmega603 AT43USB320 AT76C711 ]
enhancedcore = core ++ [ ATmega8 ATmega83 ATmega85 ]
; TODO fill in the rest.
; The instruction stream has two types of tokens:
token i(16) ; a 16 bit instruction.
offset(16) ; a 16 bit offset
; The 32 source registers are encoded using a combination of a 4-bit
; and a 1-bit field.
let Rsrclow = i[3:0]
Rsrchighbit = i[9]
Rsrc = Rsrchighbit & Rsrclow
where Rsrc[4] = Rsrchighbit
Rsrc[3:0] = Rsrclow
names [ R%n | n = 0..31 ]
Rsrcpair = i[3:0] ; Source register pairs.
names [ R%n | n = 0..31, n % 2 == 0 ]
Rdst = i[8:4] ; The 32 dst registers use 5 contiguous bits.
names [ R%n | n = 0..31 ]
Rdstpair = i[7:4] ; destination register pairs
names [ R%n | n = 0..31, n %2 == 0 ]
; Some instructions work on the 16 higher numbered registers.
Rsrchigh = i[7:4]
names [ R%n | n = 16..31 ]
Rdsthigh = i[7:4]
names [ R%n | n = 16..31 ]
; Registers used for the MUL instructions (R16-23).
Rmulsrc = i[2:0]
names [ R%n | n = 16..23 ]
Rmuldst = i[6:4]
names [ R%n | n = 16..23 ]
; 8 bit immediate value.
let Khigh = i[11:8]
Klow = i[ 3:0]
K = Khigh & Klow
where K[8:4] = Khigh
K[3:0] = Klow
; call or jmp to an absolute location
let jmpcallbit = i[1]
Jmpcall loc = i[15:9] = 0b1001010 & i[3:2] = 0b11 &
i[8:4] = loc[21:17] & i[0] = loc[16]
<+> ; next location
offset[15:0] = loc[15:0]
in
call %loc <=> Jmpcall loc & jmpcallbit = 1
jmp %loc <=> Jmpcall loc & jmpcallbit = 0
; Immediate operations on the high registers.
let immediateops@[ sbci subi sbr cbr ] = [ i[13:12] = n | n = 0..3 ]
with i[15:14] = 0b01
@immediateops %Rdsthigh, %K <=> &*
; The CPI (Compare Immediate) instruction has a different encoding.
cpi %Rdsthigh, %K <=> i[15:12] = 0b0011 &*
; Move register pair.
movw %Rdstpair, %Rsrcpair <=> i[15:8] = 0b00000001 &*
; 8x8 -> 16 bit signed multiply.
muls %Rdsthigh, %Rsrchigh <=> i[15:8] = 0b00000010 &*
; Unsigned multiply.
mul %Rdst, %Rsrc <=> i[15:10] = 0b100111 &*
; Fractional multiply instructions.
with i[15:8] = 0b00000011
fmulsu %Rmuldst, %Rmulsrc <=> i[7,3] = [1,1] &*
fmuls %Rmuldst, %Rmulsrc <=> i[7,3] = [1,0] &*
fmul %Rmuldst, %Rmulsrc <=> i[7,3] = [0,1] &*
mulsu %Rmuldst, %Rmulsrc <=> i[7,3] = [0,0] &*
; 2-operand instructions operating on all 32 registers.
let OpTwo@[ cpc sbc add cpse cp sub adc and eor or mov ] in
cpc = i[15:10] = 0b000001
with i[15:12] = 0b0010
[ and eor or mov ] = [ i[11:10] = n | n = 0..3 ]
with i[15:12] = 0b0001
[ cpse cp sub adc ] = [ i[11:10] = n | n = 0..3 ]
with i[15:11] = 0b00001
[ sbc add ] = [ i[10] = n | n = 0..1 ]
in
@OpTwo %Rdst, %Rsrc <=> &*
let OpOne = [ com neg swap inc asr lsr ror ]
with i[15:9] = 0b1001010 & i[3] = 0
[ com neg swap inc _ asr lsr ror ] = [ i[2:0] = n | n = 0..7 ]
in
@OpOne %Rdst <=> &*
let bitno = i[2:0]
let clear = i[7] in
with i[15:8] = 0b10010100 & i[3:0] = 0b1000
bclr %bitno <=> clear = 1 &*
bset %bitno <=> clear = 0 &*
; Additional aliases.
let statusbit = i[6:4]
names [ "C" "Z" "N" "V" "S" "H" "T" "I" ]
cl%statusbit <=> bclr & bitno = statusbit
se%statusbit <=> bset & bitno = statusbit
; NOP
nop <=> i[15:0] = 0
let loadstore = i[9]
; Index load/store with offset
let lddlow = i[2:0]
lddmid = i[11:10]
lddhigh = i[13]
Lddoffset = lddlow & lddmid & lddhigh
where Lddoffset[5] = lddhigh
Lddoffset[4:3] = lddmid
Lddoffset[2:0] = lddlow
yz = i[3] ; Y/Z bit for LDD with offset
names [ "Z" "Y" ]
with i[15:14] = 0b10 & i[12] = 0b0
ldd %Rdst, %yz "+" %Lddoffset <=> loadstore = 0 &*
std %Rdst, %yz "+" %Lddoffset <=> loadstore = 1 &*
; Indexed load/store with increment & decrement
let xyz = i[3:2] ; X/Y/Z for LD ops
names [ "Z" _ "Y" "X" ]
auto = i[0:1]
with i[15:10] = 0b100100 ; prefix for indexed loads
ld %Rdst, %xyz <=> loadstore = 0 & auto = 0 &*
ld %Rdst, %xyz+ <=> loadstore = 0 & auto = 1 &*
ld %Rdst, -%xyz <=> loadstore = 0 & auto = 2 &*
st %xyz, %Rdst <=> loadstore = 1 & auto = 0 &*
st %xyz+, %Rdst <=> loadstore = 1 & auto = 1 &*
st -%xyz, %Rdst <=> loadstore = 1 & auto = 2 &*
; The 'andi' instruction is 'cbi' with a negated constant.
andi %Rdsthigh, %Kcomp <=> cbr & Rdsthigh & K = ~Kcomp
; The 'ori' instruction is an alias for 'sbr'.
ori %Rdsthigh, %K <=> sbr &*
; Single operand instructions implemented using two operand ones.
clr %Rdst <=> eor & Rsrc = Rdst & Rdst
lsl %Rdst <=> add & Rsrc = Rdst & Rdst
rol %Rdst <=> adc & Rsrc = Rdst & Rdst
tst %Rdst <=> and & Rsrc = Rdst & Rdst
with i[15:9] = 0b1001010 & i[7:0] = 0b0001001
ijmp <=> indircallbit = 0 & eibit = 0
icall <=> indircallbit = 1 & eibit = 0
eijmp <=> indircallbit = 0 & eibit = 1
eicall <=> indircallbit = 1 & eibit = 1
where indircallbit = i[7]
eibit = i[4]
with i[15:8] = 0b10010101 & i[3:0] = 0b1000
let splops = i[7:4]
miscops@[ ret reti sleep break wdr lpm elpm spm ] =
[ splops = [ 0 1 8 9 10 12 13 14 ] ]
in
@miscops <=> &*
; Load program memory has two variants.
lpm <=> i[15:0] = 0b1001010111001000 ; load to R0
lpm %Rdst,Z%zincr <=> i[15:9] = 0b1001000 & i[3:1] = 0b010 &*
where zincr = i[0] names [ "" "+" ]
; Store program memory.
spm <=> i[15:0] = 0b1001010111101000
; Decrement register.
dec %Rdst <=> i[15:9] = 0b1001010 & i[3:0] = 0b1010 &*
; DES round %des, operates on R0..R15
let des = i[7:4] in
des %des <=> i[15:8] = 0b10010100 & i[3:0] = 0b1011 &*
; Add/Sub register pairs with an immediate
let addsub = i[8]
Rdstimm = i[5:4]
names [ R24 R26 R28 R30 ]
Kimm6high = i[7:6]
Kimm6low = i[3:0]
Kimm6 = Kimm6high & Kimm6low
where Kimm6[5:4] = Kimm6high
Kimm6[3:0] = Kimm6low
with i[15:9] = 0b1001011
adiw %Rdstimm, %Kimm6 <=> addsub = 0 &*
sbiw %Rdstimm, %Kimm6 <=> addsub = 1 &*
; Operations on bits in I/O registers.
let bitops@[ cbi sbic sbi sbis ] = [ instr[9:8] = n | n = 0..3 ]
ioaddr = i[7:3]
with i[15:10] = 0b100110
@bitops %ioaddr, %bit <=> &*
; IN/OUT operations
let inout = i[11]
Alow = i[3:0]
Ahigh = i[10:9]
A = Ahigh & Alow
with i[15..12] = 0b1011
in %Rdst, %A <=> inout = 0 & *
out %Rst, %A <=> inout = 1 & *
; Relative jmp/call
let reljmpcall = i[12]
reloffset = i[11:0]
with i[15:13] = 0b110
rjmp %label <=> reljmpcall = 0 & reloffset = (label - . - 1)
rcall %label <=> reljmpcall = 1 & reloffset = (label - . - 1)
; Load Immediate
ldi %Rdsthigh, %K <=> i[15:12] = 0b1110 &*
; Conditional branches
let clearedorset = i[10]
condoffset = i[9:3]
with i[15:11] = 0b11110
brbs %bitno, %label <=> clearedorset = 0 & bitno &
condoffset = (label - . - 1)
brbc %bitno, %label <=> clearedorset = 1 & bitno &
condoffset = (label - . - 1)
; Aliases
brcs %l => brbs & bitno = 0 & label = l
brlo %l => brbs & bitno = 0 & label = l
breq %l => brbs & bitno = 1 & label = l
brmi %l => brbs & bitno = 2 & label = l
brvs %l => brbs & bitno = 3 & label = l
brlt %l => brbs & bitno = 4 & label = l
brhs %l => brbs & bitno = 5 & label = l
brts %l => brbs & bitno = 6 & label = l
brie %l => brbs & bitno = 7 & label = l
brcc %l => brbc & bitno = 0 & label = l
brsh %l => brbc & bitno = 0 & label = l
brne %l => brbc & bitno = 1 & label = l
brpl %l => brbc & bitno = 2 & label = l
brvc %l => brbc & bitno = 3 & label = l
brge %l => brbc & bitno = 4 & label = l
brhc %l => brbc & bitno = 5 & label = l
brtc %l => brbc & bitno = 6 & label = l
brid %l => brbc & bitno = 7 & label = l
; BLD/BST
let bldst = i[9]
with i[15:10] = 0b111110 & i[3] = 0
bld %Rdst, %bitno <=> bldst = 0 &*
bst %Rdst, %bitno <=> bldst = 1 &*
; SBRC/SBRS
let setclr = i[9]
with i[15:10] = 0b111111 & i[3] = 0
sbrc %Rdst, %bit <=> setclr = 0 &*
sbrc %Rdst, %bit <=> setclr = 1 &*
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.