Commit 35427842 authored by Christian Dietrich's avatar Christian Dietrich

First Compiled and Executed Fibonacci

parent b76e3012
......@@ -62,6 +62,7 @@
}
\newcommand{\avrloadc}[2][-Os -mmcu=atmega8]{%
\avr@init%
\avr@compile{#2}{#1}%
\avr@ihex@load{#2.hex}%
}
......
......@@ -103,16 +103,23 @@
\xdef#2{\@tmpa\@tmpa\@tmpa\@tmpa\@tmpa\@tmpa\@tmpa\@tmpa#1}%
}
\def\avr@bin@wtb@helper#1#2#3#4#5#6#7#8#9\@nnil{%
#9%
\def\avr@bin@word@low#1#2{%
\edef\@tempa{#1}%
\edef#2{\expandafter\avr@bin@word@low@helper\@tempa\@nnil}%
}
\def\avr@bin@word@low@helper#1#2#3#4#5#6#7#8#9\@nnil{#9}
% \avr@bin@wtb bs:word, \result = ((uint8_t) bs)
\def\avr@bin@wtb#1#2{%
\def\avr@bin@word@high#1#2{%
\edef\@tempa{#1}%
\edef#2{\expandafter\avr@bin@wtb@helper\@tempa\@nnil}%
\edef#2{\expandafter\avr@bin@word@high@helper\@tempa\@nnil}%
}
\def\avr@bin@word@high@helper#1#2#3#4#5#6#7#8#9\@nnil{%
#1#2#3#4#5#6#7#8%
}
% \avr@bin@wtb bs:word, \result = ((uint8_t) bs)
\def\avr@bin@wtb{\avr@bin@word@low}
% \avr@bin@shiftleft bs:(byte|word), count, \result, \carry
% -> \result = bs << count; \carry = (bs >> count) & 1
\def\avr@bin@shiftleft#1#2#3#4{%
......
......@@ -3,14 +3,17 @@
}
\def\avr@error#1{%
\typeout{#1}\bye%
\errmessage{\the\avr@pc: #1}\bye%
}
% Execution Engine
\def\avr@instr@step{%
\avr@code@get{\avr@instr@current}%
%\avr@debug{\avr@instr@current}%
%\avr@reg@get{\csuse{avr@r24}}{\@@A}%
%\avr@reg@get{\csuse{avr@r28}}{\@@B}%
%\avr@reg@get{\csuse{avr@r29}}{\@@C}%
%\avr@debug{{r24=\@@A} {r28=\@@B} {r29=\@@C}}%
% Dispatch Instruction by prefix
\expandafter\avr@instr@dispatch\avr@instr@current\@nnil%
\relax%
......@@ -76,7 +79,9 @@
% Match also from end for these prefixes
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\csdef{avr@instr@1001010}{\avr@instr@matchend{1001010}}
% POP/PUSH
\csdef{avr@instr@1001000}{\avr@instr@matchend{1001000}}
\csdef{avr@instr@1001001}{\avr@instr@matchend{1001001}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
......@@ -109,7 +114,6 @@
\avr@reg@get{#2#3#4#5#6}{\avr@Rd}%
\avr@debug{ADD - \%#2#3#4#5#6 <- #2#3#4#5#6 + \%#1#7}%
\avr@debug{ADD - \avr@Rd <- \avr@Rd + \avr@Rr}%
\def\avr@instr@adder@RrPreprocess{\avr@bit@id}%
\csuse{avr@instr@adder@helper}%
\avr@reg@set{\avr@Rx}{#2#3#4#5#6}%
\avr@pc@inc%
......@@ -124,7 +128,6 @@
\avr@flag@get C \avr@instr@extracarry%
\avr@debug{ADC - \%#2#3#4#5#6 <- #2#3#4#5#6 + \%#1#7}%
\avr@debug{ADC - \avr@Rd <- \avr@Rd + \avr@Rr + \avr@instr@extracarry}%
\def\avr@instr@adder@RrPreprocess{\avr@bit@id}%
\csuse{avr@instr@adder@helper}%
% Set the result register
\avr@reg@set{\avr@Rx}{#2#3#4#5#6}%
......@@ -139,8 +142,7 @@
\def\avr@instr@extracarry{1}%
\avr@debug{SUB - \%#2#3#4#5#6 <- #2#3#4#5#6 + \%#1#7}%
\avr@debug{SUB - \avr@Rd <- \avr@Rd - \avr@Rr}%
\def\avr@instr@adder@RrPreprocess{\avr@bit@negate}%
\csuse{avr@instr@adder@helper}%
\csuse{avr@instr@subber@helper}%
% Set the result register
\avr@reg@set{\avr@Rx}{#2#3#4#5#6}%
\avr@pc@inc%
......@@ -154,8 +156,7 @@
\xdef \avr@instr@extracarry {\avr@bit@negate \@@carry}%
\avr@debug{SBC - \%#2#3#4#5#6 <- #2#3#4#5#6 + \%#1#7}%
\avr@debug{SBC - \avr@Rd <- \avr@Rd - \avr@Rr - \@@carry}%
\def\avr@instr@adder@RrPreprocess{\avr@bit@negate}%
\csuse{avr@instr@adder@helper}%
\csuse{avr@instr@subber@helper}%
% Set the result register
\avr@reg@set{\avr@Rx}{#2#3#4#5#6}%
\avr@pc@inc%
......@@ -168,14 +169,13 @@
\def\avr@Rr{#1#2#3#4#9}%
\def\avr@instr@extracarry{1}%
\avr@debug{SUBI - \%#2#3#4#5#6 <- #2#3#4#5#6(=\avr@Rd) - \avr@Rr}%
\def\avr@instr@adder@RrPreprocess{\avr@bit@negate}%
\csuse{avr@instr@adder@helper}%
\csuse{avr@instr@subber@helper}%
% Set the result register
\avr@reg@set{\avr@Rx}{1#5#6#7#8}%
\avr@pc@inc%
}
% SBCI - Substract Immediate
% SBCI - Substract Immediate with Carry
\def\avr@instr@SBCI{\avr@instr@gen@regconst{0100}}
\csdef{avr@instr@0100}#1#2#3#4#5#6#7#8#9\@nnil{%
\avr@reg@get{1#5#6#7#8}{\avr@Rd}%
......@@ -183,8 +183,7 @@
\avr@flag@get C \@@carry%
\xdef \avr@instr@extracarry {\avr@bit@negate \@@carry}%
\avr@debug{SBCI - \%#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}%
\csuse{avr@instr@subber@helper}%
% Set the result register
\avr@reg@set{\avr@Rx}{1#5#6#7#8}%
\avr@pc@inc%
......@@ -197,8 +196,7 @@
\avr@reg@get{#2#3#4#5#6}{\avr@Rd}%
\def\avr@instr@extracarry{1}%
\avr@debug{CP - #2#3#4#5#6(=\avr@Rd) - \%#1#7(=\avr@Rr)}%
\def\avr@instr@adder@RrPreprocess{\avr@bit@negate}%
\csuse{avr@instr@adder@helper}%
\csuse{avr@instr@subber@helper}%
% Do not set the output register
\avr@pc@inc%
}
......@@ -211,8 +209,7 @@
\avr@flag@get C \@@carry%
\xdef \avr@instr@extracarry {\avr@bit@negate \@@carry}%
\avr@debug{CP - #2#3#4#5#6(=\avr@Rd) - \%#1#7(=\avr@Rr)}%
\def\avr@instr@adder@RrPreprocess{\avr@bit@negate}%
\csuse{avr@instr@adder@helper}%
\csuse{avr@instr@subber@helper}%
% Do not set the output register
\avr@pc@inc%
}
......@@ -223,10 +220,9 @@
\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}%
\xdef \avr@instr@extracarry{1}%
\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}%
\csuse{avr@instr@subber@helper}%
% Set the result register
\avr@pc@inc%
}
......@@ -234,7 +230,6 @@
\csdef{avr@instr@adder@helper}{%
% Convert the Bitstring to Integer values
\avr@bin@tocount{\avr@Rd}{\avr@accA}%
\avr@bin@map{\avr@instr@adder@RrPreprocess}{\avr@Rr}{\avr@Rr}%
\avr@bin@tocount{\avr@Rr}{\avr@accB}%
\advance \avr@accA by \avr@accB\relax%
\advance \avr@accA by \avr@instr@extracarry\relax%
......@@ -248,13 +243,14 @@
\avr@bin@msb@get{\avr@Rr}{\@@R}%
\avr@bin@msb@get{\avr@Rd}{\@@D}%
\avr@bin@msb@get{\avr@Rx}{\@@X}%
\avr@debug{{Rr7:\@@R} {Rd7:\@@D} {R7:\@@X}}%
% \avr@debug{R: \@@R D: \@@D X:\@@X}%
\def\avr@ADD@carry{%
\@@or {\@@and \@@D {\@@not \@@X}}%
\@@or {\@@and \@@R \@@D}%
{%
\@@or{\@@and \@@R \@@D}%
{\@@and \@@R {\@@not \@@X}}}}%
\avr@flag@set C {\avr@instr@adder@RrPreprocess{\avr@ADD@carry}}%
\@@or{\@@and \@@R {\@@not \@@X}}%
{\@@and \@@X {\@@not \@@D}}}}%
\avr@flag@set C {\avr@ADD@carry}%
% Two's Complement Overflow
\def\@@tmp{\@@or%
{\@@and \@@D {\@@and \@@R {\@@not \@@X}}}%
......@@ -269,11 +265,55 @@
{%
\@@or{\@@and \@@R \@@D}%
{\@@and \@@R {\@@not \@@X}}}}%
\avr@flag@set H {\avr@instr@adder@RrPreprocess{\avr@ADD@carry}}%
\avr@flag@set H {\avr@ADD@carry}%
%% Update Dependend Flags (N, Z, S)
\avr@flags@update \avr@Rx%
}
\csdef{avr@instr@subber@helper}{%
% Convert the Bitstring to Integer values
\avr@bin@tocount{\avr@Rd}{\avr@accA}%
\avr@bin@negate{\avr@Rr}{\@@Rr}%
\avr@bin@tocount{\@@Rr}{\avr@accB}%
\advance \avr@accA by \avr@accB\relax%
\advance \avr@accA by \avr@instr@extracarry\relax%
\avr@count@modulo@byte{\avr@accA}%
\avr@count@tobin@b{\avr@accA}{\avr@Rx}%
% Calculate the Flags
\let\@@not=\avr@bit@negate%
\let\@@and=\avr@bit@and%
\let\@@or=\avr@bit@or%
%% Carry
\avr@bin@msb@get{\avr@Rr}{\@@R}%
\avr@bin@msb@get{\avr@Rd}{\@@D}%
\avr@bin@msb@get{\avr@Rx}{\@@X}%
\avr@debug{{Rr7:\@@R} {Rd7:\@@D} {R7:\@@X}}%
\def\avr@ADD@carry{%
\@@or {\@@and {\@@not \@@D} \@@R}%
{%
\@@or{\@@and \@@R \@@X}%
{\@@and \@@X {\@@not \@@D}}}}%
\avr@flag@set C {\avr@ADD@carry}%
% Two's Complement Overflow
\def\@@tmp{\@@or%
{\@@and \@@D {\@@and {\@@not \@@R} {\@@not \@@X}}}%
{\@@and {\@@not \@@D} {\@@and \@@R \@@X}}}%
\avr@flag@set V \@@tmp%
% Half Carry
\avr@bin@getbit{\avr@Rr}{3}{\@@R}%
\avr@bin@getbit{\avr@Rd}{3}{\@@D}%
\avr@bin@getbit{\avr@Rx}{3}{\@@X}%
\def\avr@ADD@carry{%
\@@or {\@@and {\@@not \@@D} \@@R}%
{%
\@@or{\@@and \@@R \@@X}%
{\@@and \@@X {\@@not \@@D}}}}%
\avr@flag@set H {\avr@ADD@carry}%
%% Update Dependend Flags (N, Z, S)
\avr@flags@update \avr@Rx%
}
% LDI -- Load Immediate Value
\def\avr@instr@LDI{\avr@instr@gen@regconst{1110}}
\def\avr@instr@SER#1#2{\avr@instr@gen@regconst{1110}{#1}{#2}{11111111}}
......@@ -308,6 +348,16 @@
#2=\avr@count@tmpa\relax%
}
\def\avr@instr@rjump@dec#1#2{%
\avr@bin@tocount{0000#1}{\avr@count@tmpa}%
\ifnum \avr@count@tmpa > 2047%
\avr@count@tmpb=\avr@count@tmpa%
\avr@count@tmpa=-4096%
\advance \avr@count@tmpa by \avr@count@tmpb\relax%
\fi%
#2=\avr@count@tmpa\relax%
}
% BRBC -- Branch if Bit in SREG is cleared
\def\avr@instr@BRBC#1#2#3{% ADD PC, Bit, Offset
\avr@instr@jump@enc{#3}{\@@offset}%
......@@ -417,6 +467,52 @@
\avr@pc@inc%
}
% RJMP
% #1 = Offset
% FIXME latex assembler
\csdef{avr@instr@1100}#1\@nnil{
\avr@instr@rjump@dec{#1}{\avr@count@tmpa}%
\avr@debug{RJMP \the\avr@count@tmpa}%
\avr@pc@add{\avr@count@tmpa}%
\avr@pc@inc%
}
% RCALL
\csdef{avr@instr@1101}#1\@nnil{
\avr@count@tobin@w{\the\avr@pc}{\@@pc}%
\avr@instr@rjump@dec{#1}{\avr@count@tmpa}%
\avr@reg@get{\csuse{avr@r24}}{\@@A}%
\avr@reg@get{\csuse{avr@r25}}{\@@B}%
\avr@reg@get{\csuse{avr@r26}}{\@@C}%
\avr@debug{RCALL \the\avr@count@tmpa {r24:\@@A} {r25:\@@B} {r26:\@@C}}%
\avr@pc@add{\avr@count@tmpa}%
\avr@bin@word@low{\@@pc}{\@@low}%
\avr@bin@word@high{\@@pc}{\@@high}%
\avr@mem@set{\@@low}{\the\avr@stackptr}%
\advance\avr@stackptr by -1\relax%
\avr@mem@set{\@@high}{\the\avr@stackptr}%
\advance\avr@stackptr by -1\relax%
\avr@pc@inc%
\avr@debug{ done}%
}
% RET
\def\avr@instr@RET#1{%
\avr@code@set{1001010100001000}{#1}%
}
\csdef{avr@instr@1001010100001000}\@nnil{%
\avr@reg@get{\csuse{avr@r24}}{\@@X}%
\avr@debug{RET (r24=\@@X)}%
\advance\avr@stackptr by 1\relax
\avr@mem@get{\the\avr@stackptr}{\@@high}%
\advance\avr@stackptr by 1\relax
\avr@mem@get{\the\avr@stackptr}{\@@low}%
\avr@bin@tocount{\@@high \@@low}{\avr@pc}%
\avr@pc@inc\relax%
\avr@debug{ done }%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Data transfert instructions
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
......@@ -444,6 +540,30 @@
\avr@pc@inc%
}
% PUSH
\def\avr@instr@PUSH#1#2{% PC, Reg
\avr@code@set{1001001#21111}{#1}%
}
\csdef{avr@instr@1001001:1111}#1\@nnil{%
\avr@reg@get{#1}{\avr@Rr}%
\avr@debug{PUSH #1(=\avr@Rr)}%
\avr@mem@set{\avr@Rr}{\the\avr@stackptr}%
\advance\avr@stackptr by -1\relax%
\avr@pc@inc%
}
% POP
\def\avr@instr@POP#1#2{% PC, Reg
\avr@code@set{1001000#21111}{#1}%
}
\csdef{avr@instr@1001000:1111}#1\@nnil{%
\advance\avr@stackptr by 1\relax%
\avr@debug{POP #1}%
\avr@mem@get{\the\avr@stackptr}{\avr@Rr}%
\avr@reg@set{\avr@Rr}{#1}%
\avr@pc@inc%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
......@@ -615,8 +735,7 @@
\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}%
\csuse{avr@instr@subber@helper}%
% Set the result register
\avr@reg@set{\avr@Rx}{#1}%
\avr@pc@inc%
......
......@@ -5,6 +5,7 @@
\avr@flag@init%
\avr@reg@init%
\avr@pc@init%
\avr@stack@init%
}
\newcount\avr@accA
......@@ -94,8 +95,8 @@
\def\avr@flags@update#1{%
% Negate Flag
\avr@bin@msb@get{#1}{\@@X}%
\avr@flag@set N \@@X%
\avr@bin@msb@get{#1}{\@@N}%
\avr@flag@set N \@@N%
% Zero Flag
\avr@bin@tocount{#1}{\avr@count@tmpa}%
\ifnum \avr@count@tmpa = 0%
......@@ -105,8 +106,8 @@
\fi%
% Signed Flag
\avr@flag@get V \@@V%
\edef\@@tmp{\avr@bit@xor \@@X \@@V}%
\avr@flag@set S \@@V%
\edef\@@tmp{\avr@bit@xor \@@N \@@V}%
\avr@flag@set S \@@tmp%
}
%% Registers
......@@ -211,6 +212,47 @@
\csxdef{avr@code@#2}{#1}%
}
%% RAM
\newcount\avr@stackptr
\def\avr@stack@init{
\avr@stackptr=0%
}
\def\avr@stack@SPL@get#1{%
\avr@count@tobin@w{\avr@stackptr}{\@@stack}%
\avr@bin@word@low{\@@stack}{#1}%
}
\def\avr@stack@SPH@get#1{%
\avr@count@tobin@w{\avr@stackptr}{\@@stack}%
\avr@bin@word@high{\@@stack}{#1}%
}
\def\avr@stack@SPL@set#1{%
\avr@count@tobin@w{\avr@stackptr}{\@@stack}%
\avr@bin@word@high{\@@stack}{\@@high}%
\avr@bin@tocount{\@@high #1}{\avr@stackptr}%
\avr@debug{ SP=\the\avr@stackptr}
}
\def\avr@stack@SPH@set#1{%
\avr@count@tobin@w{\avr@stackptr}{\@@stack}%
\avr@bin@word@low{\@@stack}{\@@low}%
\avr@bin@tocount{#1\@@low}{\avr@stackptr}%
\avr@debug{ SP=\the\avr@stackptr}
}
\def\avr@mem@set#1#2{% Bitstring, Address (as number)
\avr@debug{ MEM W *#2=#1}%
\csxdef{avr@mem@#2}{#1}%
}
\def\avr@mem@get#1#2{% Address (as number), Target Macro
\ifcsdef{avr@mem@#1}{%
\edef#2{\csuse{avr@mem@#1}}%
}{%
\edef#2{00000000}%
}%
\avr@debug{ MEM R *#1==#2}%
}
%%% Local Variables:
......
......@@ -87,7 +87,7 @@
\avr@test@helper{00001111}{00010000}%
\avr@test@REG{r17}{11111111}%
\avr@test@SREG{00000101}%
\avr@test@SREG{00010101}%
}
\appto\avr@test{\avr@test@SUB}
......@@ -110,7 +110,7 @@
\avr@test@helper{00000000}{00000000}{00000000}{00000001}%
\avr@test@REG{r17}{11111111}%
\avr@test@REG{r18}{11111111}%
\avr@test@SREG{00100101}%
\avr@test@SREG{00110101}%
\avr@test@helper{00000000}{10000000}{00000000}{00000001}%
\avr@test@REG{r17}{00000000}%
......@@ -204,11 +204,11 @@
\avr@instr@stepn{2}%
\avr@test@REG{r30}{11111111}
\avr@test@SREG{00000101}
\avr@test@SREG{00010101}
\avr@instr@stepn{1}%
\avr@test@REG{r30}{11111101}
\avr@test@SREG{00000100}
\avr@test@SREG{00010100}
}
\preto\avr@test{\avr@test@SUBI}
......@@ -279,7 +279,7 @@
\avr@instr@stepn{2}%
\avr@test@REG{r20}{11111111}
\avr@test@SREG{00100101}
\avr@test@SREG{00110101}
\avr@instr@stepn{1}%
\avr@test@REG{r20}{00000001}
......@@ -296,7 +296,7 @@
\avr@instr@stepn{2}%
\avr@test@REG{r20}{11111110}
\avr@test@SREG{00000101}
\avr@test@SREG{00010101}
\avr@instr@stepn{1}%
\avr@test@REG{r20}{00000001}
......@@ -336,7 +336,7 @@
\avr@instr@stepn{2}%
\avr@test@REG{r20}{11000100}
\avr@test@SREG{00000101}
\avr@test@SREG{00010101}
}
\preto\avr@test{\avr@test@ASR}
......@@ -372,7 +372,7 @@
\avr@instr@stepn{1}%
\avr@test@REG{r20}{10000000}
\avr@test@SREG{00011100}
\avr@test@SREG{00001100}
\avr@instr@stepn{1}%
\avr@test@REG{r20}{01000000}
......@@ -385,11 +385,64 @@ int main() { }
\end{filecontents*}
\def\avr@test@emptymain{%
\avr@test@setup{Empty Main Function}%
\avrloadc{empty-main.c}
\avr@instr@stepn{3}
\avr@instr@stepn{50}
}
\preto\avr@test{\avr@test@emptymain}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{filecontents*}{sum-rec.c}
#include <avr/io.h>
char sum(char n) {
if (n <= 1) {
return n;
}
return n + sum(n-1);
}
int main() {
UDR = sum(4);
asm volatile ("break");
}
\end{filecontents*}
\def\avr@test@sumRec{%
\avr@test@setup{Summing Recursive}%
\avrloadc{sum-rec.c}
\avr@instr@stepn{1000}
\avr@test@REG{r24}{00001010}
}
\preto\avr@test{\avr@test@sumRec}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\begin{filecontents*}{fibonacci-rec.c}
#include <avr/io.h>
char fib(char n) {
if (n <= 1) {
return 1;
}
return fib(n-1) + fib(n-2);
}
int main() {
UDR = fib(5);
asm volatile ("break");
}
\end{filecontents*}
\def\avr@test@fibRec{%
\avr@test@setup{Fibonacci Recursive}%
\avrloadc{fibonacci-rec.c}
\avr@instr@stepn{1000}
\avr@test@REG{r24}{00001000}
}
\preto\avr@test{\avr@test@fibRec}
%%% Local Variables:
%%% mode: latex
......
......@@ -15,6 +15,7 @@
\input{avr.bitops}
\input{avr.memory}
\input{avr.instr}
\input{avr.io}
\input{avr.testsuite}
......
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