Commit 0dee263e authored by Christian Dietrich's avatar Christian Dietrich

More Instruction Implementations

parent 4613bcdd
......@@ -78,6 +78,24 @@
\expandafter\avr@bin@getbit@helper\@tmpa\@nnil%
}
\def\avr@bin@setbit#1#2#3#4{%
\def\@tempa{}%
\avr@count@tmpa=7%
\advance\avr@count@tmpa by -#2\relax%
\def\avr@bin@setbit@helper##1##2\@nnil{%
\ifnum \avr@count@tmpa = 0%
\xdef\@tempa{\@tempa #3##2}%
\else%
\advance\avr@count@tmpa by -1\relax%
\xdef\@tempa{\@tempa ##1}%
\avr@bin@setbit@helper##2\@nnil%
\fi%
}%
\edef\@tmpb{#1}%
\expandafter\avr@bin@setbit@helper\@tmpb\@nnil%
\edef#4{\@tempa}
}
% \avr@bin@btw bs:byte, \result -> \result = 00000000+bs
\def\avr@bin@btw#1#2{\xdef#2{00000000#1}}
\def\avr@bin@btw@sign#1#2{%
......
......@@ -10,6 +10,7 @@
% Execution Engine
\def\avr@instr@step{%
\avr@code@get{\avr@instr@current}%
%\avr@debug{\avr@instr@current}%
% Dispatch Instruction by prefix
\expandafter\avr@instr@dispatch\avr@instr@current\@nnil%
\relax%
......@@ -52,6 +53,31 @@
}}}}}}}}}%
}
\def\avr@instr@matchend#1#2#3#4#5#6#7#8#9\@nnil{%
\ifcsdef{avr@instr@#1:#2#3#4#5#6#7#8#9}{%
\csuse{avr@instr@#1:#2#3#4#5#6#7#8#9}\@nnil%
}{\ifcsdef{avr@instr@#1:#3#4#5#6#7#8#9}{%
\csuse{avr@instr@#1:#3#4#5#6#7#8#9}#2\@nnil%
}{\ifcsdef{avr@instr@#1:#4#5#6#7#8#9}{%
\csuse{avr@instr@#1:#4#5#6#7#8#9}#2#3\@nnil%
}{\ifcsdef{avr@instr@#1:#5#6#7#8#9}{%
\csuse{avr@instr@#1:#5#6#7#8#9}#2#3#4\@nnil%
}{\ifcsdef{avr@instr@#1:#6#7#8#9}{%
\csuse{avr@instr@#1:#6#7#8#9}#2#3#4#5\@nnil%
}{\ifcsdef{avr@instr@#1:#7#8#9}{%
\csuse{avr@instr@#1:#7#8#9}#2#3#4#5#6\@nnil%
}{\ifcsdef{avr@instr@#1:#9}{%
\csuse{avr@instr@#1:#9}#2#3#4#5#6#7#8\@nnil%
}{% Not found
\avr@error{Unkown Instruction: #1:#2#3#4#5#6#7#8#9}%
}}}}}}}%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Match also from end for these prefixes
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\csdef{avr@instr@1001010}{\avr@instr@matchend{1001010}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Helpers
......@@ -76,7 +102,7 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% ADD -- Add without Carry
\def\avr@instr@ADD{\avr@instr@gen@tworegs{000011}}
\def\avr@instr@LSL#1#2{\avr@instr@gen@tworegs{000011}{#1}{#2}{#2}}
\csdef{avr@instr@000011}#1#2#3#4#5#6#7\@nnil{%
\def\avr@instr@extracarry{0}%
\avr@reg@get{#1#7}{\avr@Rr}%
......@@ -91,7 +117,7 @@
% ADC -- Add with Carry
\def\avr@instr@ADC{\avr@instr@gen@tworegs{000111}}
\def\avr@instr@ROL#1#2{\avr@instr@ADC{#1}{#2}{#2}}
\csdef{avr@instr@000111}#1#2#3#4#5#6#7\@nnil{%
\avr@reg@get{#1#7}{\avr@Rr}%
\avr@reg@get{#2#3#4#5#6}{\avr@Rd}%
......@@ -166,7 +192,6 @@
% CP -- Compare without Carry
\def\avr@instr@CP{\avr@instr@gen@tworegs{000101}}
\csdef{avr@instr@000101}#1#2#3#4#5#6#7\@nnil{%
\avr@reg@get{#1#7}{\avr@Rr}%
\avr@reg@get{#2#3#4#5#6}{\avr@Rd}%
......@@ -180,7 +205,6 @@
% CPC -- Compare with Carry
\def\avr@instr@CPC{\avr@instr@gen@tworegs{000001}}
\csdef{avr@instr@000001}#1#2#3#4#5#6#7\@nnil{%
\avr@reg@get{#1#7}{\avr@Rr}%
\avr@reg@get{#2#3#4#5#6}{\avr@Rd}%
......@@ -193,6 +217,20 @@
\avr@pc@inc%
}
% CPI - Compare Immediate
\def\avr@instr@CPI{\avr@instr@gen@regconst{0011}}
\csdef{avr@instr@0011}#1#2#3#4#5#6#7#8#9\@nnil{%
\avr@reg@get{1#5#6#7#8}{\avr@Rd}%
\def\avr@Rr{#1#2#3#4#9}%
\avr@flag@get C \@@carry%
\xdef \avr@instr@extracarry {\avr@bit@negate \@@carry}%
\avr@debug{CPI - \%#2#3#4#5#6 <- #2#3#4#5#6(=\avr@Rd) - \avr@Rr -\@@carry}%
\def\avr@instr@adder@RrPreprocess{\avr@bit@negate}%
\csuse{avr@instr@adder@helper}%
% Set the result register
\avr@pc@inc%
}
\csdef{avr@instr@adder@helper}{%
% Convert the Bitstring to Integer values
\avr@bin@tocount{\avr@Rd}{\avr@accA}%
......@@ -384,7 +422,6 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% MOV
\def\avr@instr@MOV{\avr@instr@gen@tworegs{001011}}
\csdef{avr@instr@001011}#1#2#3#4#5#6#7\@nnil{%
\avr@reg@get{#1#7}{\avr@Rr}%
\avr@reg@set{\avr@Rr}{#2#3#4#5#6}%
......@@ -392,6 +429,23 @@
\avr@pc@inc%
}
% MOVW
\def\avr@instr@MOVW#1#2#3{%
\avr@bin@lsb@del{#2}{\avr@LDI@dddd}{\avr@LDI@d}%
\avr@bin@lsb@del{#3}{\avr@LDI@rrrr}{\avr@LDI@r}%
\avr@code@set{00000001\avr@LDI@dddd\avr@LDI@rrrr}{#1}%
}
\csdef{avr@instr@00000001}#1#2#3#4#5\@nnil{%
\avr@reg@get{#50}{\avr@Rr}%
\avr@reg@set{\avr@Rr}{#1#2#3#40}%
\avr@reg@get{#51}{\avr@Rd}%
\avr@reg@set{\avr@Rd}{#1#2#3#41}%
\avr@debug{MOV - #1#2#3#4[01] <- #5[01](=\avr@Rr:\avr@Rd)}
\avr@pc@inc%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Misc
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
......@@ -405,7 +459,7 @@
\avr@pc@inc%
}
\def\avr@instr@NOP#1{% BREAK PC
\def\avr@instr@NOP#1{%
\avr@code@set{0000000000000000}{#1}%
}
......@@ -460,6 +514,7 @@
}
\def\avr@instr@ORI{\avr@instr@gen@regconst{0110}}
\def\avr@instr@SBR{\avr@instr@ORI}
\csdef{avr@instr@0110}#1#2#3#4#5#6#7#8#9\@nnil{%
\avr@reg@get{1#5#6#7#8}{\avr@Rd}%
\def\avr@Rr{#1#2#3#4#9}%
......@@ -482,8 +537,167 @@
\avr@pc@inc%
}
\def\avr@instr@BSET#1#2{%
\avr@code@set{100101000#21000}{#1}%
}
\def\avr@instr@SEC#1{\avr@instr@BSET{#1}{000}}
\def\avr@instr@SEZ#1{\avr@instr@BSET{#1}{001}}
\def\avr@instr@SEN#1{\avr@instr@BSET{#1}{010}}
\def\avr@instr@SEV#1{\avr@instr@BSET{#1}{011}}
\def\avr@instr@SES#1{\avr@instr@BSET{#1}{100}}
\def\avr@instr@SEH#1{\avr@instr@BSET{#1}{101}}
\def\avr@instr@SET#1{\avr@instr@BSET{#1}{110}}
\def\avr@instr@SEI#1{\avr@instr@BSET{#1}{111}}
\def\avr@instr@BCLR#1#2{%
\avr@code@set{100101001#21000}{#1}%
}
\def\avr@instr@CLC#1{\avr@instr@BCLR{#1}{000}}
\def\avr@instr@CLZ#1{\avr@instr@BCLR{#1}{001}}
\def\avr@instr@CLN#1{\avr@instr@BCLR{#1}{010}}
\def\avr@instr@CLV#1{\avr@instr@BCLR{#1}{011}}
\def\avr@instr@CLS#1{\avr@instr@BCLR{#1}{100}}
\def\avr@instr@CLH#1{\avr@instr@BCLR{#1}{101}}
\def\avr@instr@CLT#1{\avr@instr@BCLR{#1}{110}}
\def\avr@instr@CLI#1{\avr@instr@BCLR{#1}{111}}
\def\avr@instr@BSET@helper#1#2{%
% BSET
\csdef{avr@instr@100101000#11000}\@nnil{%
\avr@debug{BSET #1 #2}%
\avr@flag@set #2 1%
\avr@pc@inc%
}%
\csdef{avr@instr@100101001#11000}\@nnil{%
\avr@debug{BCLR #2}%
\avr@flag@set #2 0%
\avr@pc@inc%
}\relax%
}
\avr@instr@BSET@helper{000}{C}
\avr@instr@BSET@helper{001}{Z}
\avr@instr@BSET@helper{010}{N}
\avr@instr@BSET@helper{011}{V}
\avr@instr@BSET@helper{100}{S}
\avr@instr@BSET@helper{101}{H}
\avr@instr@BSET@helper{110}{T}
\avr@instr@BSET@helper{111}{I}
\def\avr@instr@BST#1#2#3{\avr@code@set{1111101#20#3}{#1}}
\csdef{avr@instr@1111101}#1#2#3#4#5#6\@nnil{%
\avr@reg@get{#1#2#3#4#5}{\avr@Rd}%
\avr@bin@tocount{0000#6}{\avr@count@tmpa}%
\edef\@@X{\the\avr@count@tmpa}%
\avr@debug{BST T <- #1#2#3#4#5(=\avr@Rd):\@@X}%
\avr@bin@getbit{\avr@Rd}{\@@X}{\@@T}%
\avr@flag@set T \@@T%
\avr@pc@inc%
}
\def\avr@instr@BLD#1#2#3{\avr@code@set{1111100#20#3}{#1}}
\csdef{avr@instr@1111100}#1#2#3#4#5#6\@nnil{%
\avr@bin@tocount{0000#6}{\avr@count@tmpa}%
\avr@reg@get{#1#2#3#4#5}{\avr@Rd}%
\edef\@@X{\the\avr@count@tmpa}%
\avr@flag@get T \@@T%
\avr@debug{BLD #1#2#3#4#5(=\avr@Rd) |= \@@T<<\@@X}%
\avr@bin@setbit{\avr@Rd}{\@@X}{\@@T}{\avr@Rd}%
\avr@reg@set{\avr@Rd}{#1#2#3#4#5}%
\avr@pc@inc%
}
\def\avr@instr@NEG#1#2{\avr@code@set{1001010#20001}{#1}}
\csdef{avr@instr@1001010:0001}#1\@nnil{%
\avr@reg@get{#1}{\avr@Rr}%
\avr@debug{NEG: #1(=\avr@Rr)}%
\def\avr@Rd{00000000}%
\def\avr@instr@extracarry{1}%
\def\avr@instr@adder@RrPreprocess{\avr@bit@negate}%
\csuse{avr@instr@adder@helper}%
% Set the result register
\avr@reg@set{\avr@Rx}{#1}%
\avr@pc@inc%
}
\def\avr@instr@COM#1#2{\avr@code@set{1001010#20000}{#1}}
\csdef{avr@instr@1001010:0000}#1\@nnil{%
\avr@reg@get{#1}{\avr@Rr}%
\avr@debug{COM: #1(=\avr@Rr)}%
\avr@bin@negate{\avr@Rr}{\avr@Rx}%
\avr@flag@set C 1%
\avr@flag@set V 0%
\avr@flags@update \avr@Rx%
% Set the result register
\avr@reg@set{\avr@Rx}{#1}%
\avr@pc@inc%
}
% Skip if Bit in Register is Set (or not)
\def\avr@instr@SBRC#1#2#3{\avr@code@set{1111110#20#3}{#1}}
\def\avr@instr@SBRS#1#2#3{\avr@code@set{1111111#20#3}{#1}}
\csdef{avr@instr@111111}#1#2#3#4#5#6#7\@nnil{%
\def\@@required{#1}% 1 if if set
\avr@reg@get{#2#3#4#5#6}{\avr@Rr}%
\avr@bin@tocount{0000#7}{\avr@count@tmpa}%
\edef\@@bit{\the\avr@count@tmpa}%
\avr@bin@getbit{\avr@Rr}{\@@bit}{\@@found}%
\avr@debug{SBR[SC] Skip iff \avr@Rr:\@@bit(\@@found) == \@@required}%
\avr@count@tmpa=\@@found%
\avr@count@tmpb=\@@required\relax%
\ifnum \avr@count@tmpa = \avr@count@tmpb%
\avr@debug{SKIP one instruction}%
\avr@pc@inc%
\fi%
\avr@pc@inc%
}
\def\avr@instr@ASR#1#2{\avr@code@set{1001010#20101}{#1}}
\csdef{avr@instr@1001010:0101}#1\@nnil{%
\avr@reg@get{#1}{\avr@Rr}%
\avr@debug{ASR: #1(=\avr@Rr)}%
\avr@bin@shiftright@arith{\avr@Rr}{1}{\avr@Rx}{\@@carry}%
\avr@bin@msb@get{\avr@Rx}{\@@N}%
\avr@flag@set C \@@carry%
\avr@flag@set V {\avr@bit@xor \@@carry \@@N}%
\avr@flags@update \avr@Rx%
\avr@reg@set{\avr@Rx}{#1}%
\avr@pc@inc%
}
% LSL is implemented as ADD
\def\avr@instr@LSR#1#2{\avr@code@set{1001010#20110}{#1}}
\csdef{avr@instr@1001010:0110}#1\@nnil{%
\avr@reg@get{#1}{\avr@Rr}%
\avr@debug{LSL: #1(=\avr@Rr)}%
\avr@bin@shiftright{\avr@Rr}{1}{\avr@Rx}{\@@carry}%
\avr@bin@msb@get{\avr@Rx}{\@@N}%
\avr@flag@set C \@@carry%
\avr@flag@set V {\avr@bit@xor \@@carry \@@N}%
\avr@flags@update \avr@Rx%
\avr@reg@set{\avr@Rx}{#1}%
\avr@pc@inc%
}
% ROL is implemented as ADD
\def\avr@instr@ROR#1#2{\avr@code@set{1001010#20111}{#1}}
\csdef{avr@instr@1001010:0111}#1\@nnil{%
\avr@reg@get{#1}{\avr@Rr}%
\avr@flag@get C \@@carry%
\avr@debug{ROR: #1(=\@@carry:\avr@Rr)}%
\avr@bin@lsb@del{\@@carry\avr@Rr}{\avr@Rx}{\@@carry}%
\avr@bin@msb@get{\avr@Rx}{\@@N}%
\avr@flag@set C \@@carry%
\avr@flag@set V {\avr@bit@xor \@@carry \@@N}%
\avr@flags@update \avr@Rx%
\avr@reg@set{\avr@Rx}{#1}%
\avr@pc@inc%
}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "avr.tex"
......
......@@ -212,6 +212,174 @@
}
\preto\avr@test{\avr@test@SUBI}
\def\avr@test@CPI{%
\avr@test@setup{CPI}%
\avr@instr@LDI{0}{\csuse{avr@r30}}{00001111}%
\avr@instr@CPI{1}{\csuse{avr@r30}}{00001111}%
\avr@instr@stepn{2}%
\avr@test@REG{r30}{00001111}
\avr@test@SREG{00000010}
}
\preto\avr@test{\avr@test@CPI}
\def\avr@test@MOVW{%
\avr@test@setup{MOVW}%
\avr@instr@LDI{0}{\csuse{avr@r30}}{00001111}%
\avr@instr@LDI{1}{\csuse{avr@r31}}{11110000}%
\avr@instr@MOVW{2}{\csuse{avr@r2}}{\csuse{avr@r30}}%
\avr@instr@stepn{3}%
\avr@test@REG{r2}{00001111}
\avr@test@REG{r3}{11110000}
\avr@test@SREG{00000000}
}
\preto\avr@test{\avr@test@MOVW}
\def\avr@test@BSET{%
\avr@test@setup{BSET}%
\avr@instr@SEI{0}%
\avr@instr@SEC{1}%
\avr@instr@CLI{2}%
\avr@instr@stepn{2}%
\avr@test@SREG{10000001}
\avr@instr@stepn{1}%
\avr@test@SREG{00000001}
}
\preto\avr@test{\avr@test@BSET}
\def\avr@test@BST{%
\avr@test@setup{BST}%
\avr@instr@LDI{0}{\csuse{avr@r31}}{00010000}%
\avr@instr@BST{1}{\csuse{avr@r31}}{100}%
\avr@instr@BLD{2}{\csuse{avr@r31}}{000}%
\avr@instr@CLT{3}
\avr@instr@BLD{4}{\csuse{avr@r31}}{100}%
\avr@instr@stepn{2}%
\avr@test@SREG{01000000}
\avr@instr@stepn{1}
\avr@test@REG{r31}{00010001}
\avr@instr@stepn{2}%
\avr@test@SREG{00000000}
\avr@test@REG{r31}{00000001}
}
\preto\avr@test{\avr@test@BST}
\def\avr@test@NEG{%
\avr@test@setup{NEG}%
\avr@instr@LDI{0}{\csuse{avr@r20}}{00000001}%
\avr@instr@NEG{1}{\csuse{avr@r20}}%
\avr@instr@NEG{2}{\csuse{avr@r20}}%
\avr@instr@stepn{2}%
\avr@test@REG{r20}{11111111}
\avr@test@SREG{00100101}
\avr@instr@stepn{1}%
\avr@test@REG{r20}{00000001}
\avr@test@SREG{00100001}
}
\preto\avr@test{\avr@test@NEG}
\def\avr@test@COM{%
\avr@test@setup{COM}%
\avr@instr@LDI{0}{\csuse{avr@r20}}{00000001}%
\avr@instr@COM{1}{\csuse{avr@r20}}%
\avr@instr@COM{2}{\csuse{avr@r20}}%
\avr@instr@stepn{2}%
\avr@test@REG{r20}{11111110}
\avr@test@SREG{00000101}
\avr@instr@stepn{1}%
\avr@test@REG{r20}{00000001}
\avr@test@SREG{00000001}
}
\preto\avr@test{\avr@test@COM}
\def\avr@test@SBR{%
\avr@test@setup{SBR[CS]}%
\avr@instr@LDI{0}{\csuse{avr@r20}}{00001000}%
\avr@instr@SBRS{1}{\csuse{avr@r20}}{011}%
\avr@instr@LDI{2}{\csuse{avr@r20}}{00001111}%
\avr@instr@NOP{3}
\avr@instr@stepn{3}%
\avr@test@REG{r20}{00001000}
\avr@instr@SBRS{4}{\csuse{avr@r20}}{010}%
\avr@instr@LDI{5}{\csuse{avr@r20}}{00001111}%
\avr@instr@NOP{6}
\avr@instr@stepn{2}%
\avr@test@REG{r20}{00001111}
}
\preto\avr@test{\avr@test@SBR}
\def\avr@test@ASR{%
\avr@test@setup{ASR}%
\avr@instr@LDI{0}{\csuse{avr@r20}}{00001001}%
\avr@instr@ASR{1}{\csuse{avr@r20}}%
\avr@instr@LDI{2}{\csuse{avr@r20}}{10001001}%
\avr@instr@ASR{3}{\csuse{avr@r20}}%
\avr@instr@stepn{2}%
\avr@test@REG{r20}{00000100}
\avr@test@SREG{00011001}
\avr@instr@stepn{2}%
\avr@test@REG{r20}{11000100}
\avr@test@SREG{00000101}
}
\preto\avr@test{\avr@test@ASR}
\def\avr@test@LSR{%
\avr@test@setup{LSR}%
\avr@instr@LDI{0}{\csuse{avr@r20}}{00001001}%
\avr@instr@LSR{1}{\csuse{avr@r20}}%
\avr@instr@LDI{2}{\csuse{avr@r20}}{10001001}%
\avr@instr@LSR{3}{\csuse{avr@r20}}%
\avr@instr@stepn{2}%
\avr@test@REG{r20}{00000100}
\avr@test@SREG{00011001}
\avr@instr@stepn{2}%
\avr@test@REG{r20}{01000100}
\avr@test@SREG{00011001}
}
\preto\avr@test{\avr@test@LSR}
\def\avr@test@ROR{%
\avr@test@setup{ROR}%
\avr@instr@LDI{0}{\csuse{avr@r20}}{00000001}%
\avr@instr@ROR{1}{\csuse{avr@r20}}%
\avr@instr@ROR{2}{\csuse{avr@r20}}%
\avr@instr@ROR{3}{\csuse{avr@r20}}%
\avr@instr@stepn{2}%
\avr@test@REG{r20}{00000000}
\avr@test@SREG{00011011}
\avr@instr@stepn{1}%
\avr@test@REG{r20}{10000000}
\avr@test@SREG{00011100}
\avr@instr@stepn{1}%
\avr@test@REG{r20}{01000000}
\avr@test@SREG{00000000}
}
\preto\avr@test{\avr@test@ROR}
%%% Local Variables:
%%% mode: latex
%%% TeX-master: "avr.tex"
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment