diff options
author | Kai Wang <kaiw@FreeBSD.org> | 2014-01-15 08:43:20 +0000 |
---|---|---|
committer | Kai Wang <kaiw@FreeBSD.org> | 2014-01-15 08:43:20 +0000 |
commit | 5265ace0e440a23fb522c516f4ee20f43eaed2b3 (patch) | |
tree | 13068447bb61372f7540b168e913b8eb88ef7578 /isa/avr.isa | |
download | src-5265ace0e440a23fb522c516f4ee20f43eaed2b3.tar.gz src-5265ace0e440a23fb522c516f4ee20f43eaed2b3.zip |
Notes
Diffstat (limited to 'isa/avr.isa')
-rw-r--r-- | isa/avr.isa | 280 |
1 files changed, 280 insertions, 0 deletions
diff --git a/isa/avr.isa b/isa/avr.isa new file mode 100644 index 000000000000..a6b7381795c5 --- /dev/null +++ b/isa/avr.isa @@ -0,0 +1,280 @@ +; +; $Id: avr.isa 2899 2013-01-16 05:17:02Z jkoshy $ +; +; 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 &* |