Commit 214ec7b2 authored by Christian Dietrich's avatar Christian Dietrich

Implement Load and Store Command for Memory

parent 35427842
......@@ -37,6 +37,13 @@
% \avr@bin@id{A}{\result} -> \result = A
\def\avr@bin@id{\avr@bin@map{\avr@bit@id}}
\csdef{avr@bit@mask@00}{.}
\csdef{avr@bit@mask@01}{0}
\csdef{avr@bit@mask@10}{.}
\csdef{avr@bit@mask@11}{1}
\def\avr@bit@mask#1#2{\csuse{avr@bit@mask@#1#2}}
% \avr@bin@mask{value}{mask}{\result} -> \result = ...
\def\avr@bin@mask{\avr@bin@zipmap{\avr@bit@mask}}
\csdef{avr@bit@and@00}{0}
\csdef{avr@bit@and@01}{0}
......
......@@ -52,7 +52,7 @@
}{\ifcsdef{avr@instr@#1}{%
\csuse{avr@instr@#1}#2#3#4#5#6#7#8#9\@nnil%
}{% Not found
\avr@error{Unkown Instruction: #1#2#3#4#5#6#7#8#9}%
\avr@instr@matchspecial{#1#2#3#4#5#6#7#8#9}%
}}}}}}}}}%
}
......@@ -72,9 +72,21 @@
}{\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}%
\avr@instr@matchspecial{#1#2#3#4#5#6#7#8#9}%
}}}}}}}%
}
\def\avr@instr@matchspecial#1{%
\avr@bin@mask{#1}{1101001000001000}{\@@masked}%
\avr@bin@mask{#1}{0010110111110111}{\@@args}%
\ifcsdef{avr@instr@special@\@@masked}{%
\def\@tempa{\csuse{avr@instr@special@\@@masked}}%
\expandafter\@tempa\@@args\@nnil%
}{%
\avr@error{Unkown Instruction: #1}%
}%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Match also from end for these prefixes
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
......@@ -82,6 +94,9 @@
% POP/PUSH
\csdef{avr@instr@1001000}{\avr@instr@matchend{1001000}}
\csdef{avr@instr@1001001}{\avr@instr@matchend{1001001}}
% LD(XYZ)
\csdef{avr@instr@1000000}{\avr@instr@matchend{1000000}}
\csdef{avr@instr@1000001}{\avr@instr@matchend{1000001}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
......@@ -101,6 +116,10 @@
\avr@code@set{#1\avr@LDI@H\avr@LDI@dddd\avr@LDI@L}{#2}%
}
\def\avr@instr@gen@onereg#1#2#3#4{%
\avr@code@set{#1#4#2}{#3}%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Arithmetic instructions
......@@ -565,6 +584,180 @@
\avr@pc@inc%
}
\newcount\avr@addr
\def\avr@instr@LDD@helper#1#2#3#4{%
% PreIncrement, RegisterW, PostIncrement, Target
\avr@regw@get{\csuse{avr@#2}}{\@@addr}%
\avr@debug{LD *(#1:#2:#3,#2=\@@addr)}%
\avr@bin@tocount{\@@addr}{\avr@addr}%
\advance \avr@addr by #1\relax%
\avr@count@overflow{\avr@addr}\relax%
\avr@mem@get{\the\avr@addr}{\avr@Rx}%
\advance \avr@addr by #3\relax%
\avr@count@overflow{\avr@addr}\relax%
\avr@count@tobin@w{\avr@addr}{\@@addr}%
\avr@regw@set{\@@addr}{\csuse{avr@#2}}%
\avr@reg@set{\avr@Rx}{#4}%
\avr@pc@inc%
}
\def\avr@instr@STS@helper#1#2#3#4{%
% PreIncrement, RegisterW, PostIncrement, SourceReg
\avr@regw@get{\csuse{avr@#2}}{\@@addr}%
\avr@reg@get{#4}{\avr@Rd}%
\avr@debug{ST *(#1:#2:#3,#2=\@@addr)}%
\avr@bin@tocount{\@@addr}{\avr@addr}%
\advance \avr@addr by #1\relax%
\avr@count@overflow{\avr@addr}\relax%
\avr@mem@set{\avr@Rd}{\the\avr@addr}%
\advance \avr@addr by #3\relax%
\avr@count@overflow{\avr@addr}\relax%
\avr@count@tobin@w{\avr@addr}{\@@addr}%
\avr@regw@set{\@@addr}{\csuse{avr@#2}}%
\avr@pc@inc%
}
% LD(X)
\def\avr@instr@LDX{\avr@instr@gen@onereg{1001000}{1100}}
\def\avr@instr@LDXp{\avr@instr@gen@onereg{1001000}{1101}}
\def\avr@instr@LDmX{\avr@instr@gen@onereg{1001000}{1110}}
\csdef{avr@instr@1001000:1100}#1\@nnil{%
\avr@instr@LDD@helper{0}{X}{0}{#1}%
}
\csdef{avr@instr@1001000:1101}#1\@nnil{%
\avr@instr@LDD@helper{0}{X}{1}{#1}%
}
\csdef{avr@instr@1001000:1110}#1\@nnil{%
\avr@instr@LDD@helper{-1}{X}{0}{#1}%
}
% LD(Y)
\def\avr@instr@LDY{\avr@instr@gen@onereg{1000000}{1000}}
\def\avr@instr@LDYp{\avr@instr@gen@onereg{1001000}{1001}}
\def\avr@instr@LDmY{\avr@instr@gen@onereg{1001000}{1010}}
\csdef{avr@instr@1000000:1000}#1\@nnil{%
\avr@instr@LDD@helper{0}{Y}{0}{#1}%
}
\csdef{avr@instr@1001000:1001}#1\@nnil{%
\avr@instr@LDD@helper{0}{Y}{1}{#1}%
}
\csdef{avr@instr@1001000:1010}#1\@nnil{%
\avr@instr@LDD@helper{-1}{Y}{0}{#1}%
}
% LD(Z)
\def\avr@instr@LDZ{\avr@instr@gen@onereg{1000000}{0000}}
\def\avr@instr@LDZp{\avr@instr@gen@onereg{1001000}{0001}}
\def\avr@instr@LDmZ{\avr@instr@gen@onereg{1001000}{0010}}
\csdef{avr@instr@1000000:0000}#1\@nnil{%
\avr@instr@LDD@helper{0}{Z}{0}{#1}%
}
\csdef{avr@instr@1001000:0001}#1\@nnil{%
\avr@instr@LDD@helper{0}{Z}{1}{#1}%
}
\csdef{avr@instr@1001000:0010}#1\@nnil{%
\avr@instr@LDD@helper{-1}{Z}{0}{#1}%
}
% ST(X,Y,Z)
\def\avr@instr@STX{\avr@instr@gen@onereg{1001001}{1100}}
\def\avr@instr@STXp{\avr@instr@gen@onereg{1001001}{1101}}
\def\avr@instr@STmX{\avr@instr@gen@onereg{1001001}{1110}}
\csdef{avr@instr@1001001:1100}#1\@nnil{%
\avr@instr@STS@helper{0}{X}{0}{#1}%
}
\csdef{avr@instr@1001001:1101}#1\@nnil{%
\avr@instr@STS@helper{0}{X}{1}{#1}%
}
\csdef{avr@instr@1001001:1110}#1\@nnil{%
\avr@instr@STS@helper{-1}{X}{0}{#1}%
}
\def\avr@instr@STY{\avr@instr@gen@onereg{1000001}{1000}}
\def\avr@instr@STYp{\avr@instr@gen@onereg{1001001}{1001}}
\def\avr@instr@STmY{\avr@instr@gen@onereg{1001001}{1010}}
\csdef{avr@instr@1000001:1000}#1\@nnil{%
\avr@instr@STS@helper{0}{Y}{0}{#1}%
}
\csdef{avr@instr@1001001:1001}#1\@nnil{%
\avr@instr@STS@helper{0}{Y}{1}{#1}%
}
\csdef{avr@instr@1001001:1010}#1\@nnil{%
\avr@instr@STS@helper{-1}{Y}{0}{#1}%
}
\def\avr@instr@STZ{\avr@instr@gen@onereg{1000001}{0000}}
\def\avr@instr@STZp{\avr@instr@gen@onereg{1001001}{0001}}
\def\avr@instr@STmZ{\avr@instr@gen@onereg{1001001}{0010}}
\csdef{avr@instr@1000001:0000}#1\@nnil{%
\avr@instr@STS@helper{0}{Z}{0}{#1}%
}
\csdef{avr@instr@1001001:0001}#1\@nnil{%
\avr@instr@STS@helper{0}{Z}{1}{#1}%
}
\csdef{avr@instr@1001001:0010}#1\@nnil{%
\avr@instr@STS@helper{-1}{Z}{0}{#1}%
}
% Special Stores & Loads
% LD R <- Y+q
\csdef{avr@instr@special@10.0..0.....1...}..#1.#2.#3.#4\@nnil{%
\avr@debug{LD reg(#3) <- Y+#1#2#4}%
\avr@regw@get{\csuse{avr@Y}}{\@@addr}%
\avr@bin@tocount{\@@addr}{\avr@addr}%
\avr@bin@tocount{00#1#2#4}{\avr@count@tmpa}%
\advance \avr@addr by \avr@count@tmpa\relax%
\avr@count@overflow{\avr@addr}\relax%
\avr@mem@get{\the\avr@addr}{\avr@Rd}%
\avr@reg@set{\avr@Rd}{#3}%
\avr@pc@inc%
}
% LD R <- Z+q
\csdef{avr@instr@special@10.0..0.....0...}..#1.#2.#3.#4\@nnil{%
\avr@debug{LD reg(#3) <- Z+#1#2#4}%
\avr@regw@get{\csuse{avr@Z}}{\@@addr}%
\avr@bin@tocount{\@@addr}{\avr@addr}%
\avr@bin@tocount{00#1#2#4}{\avr@count@tmpa}%
\advance \avr@addr by \avr@count@tmpa\relax%
\avr@count@overflow{\avr@addr}\relax%
\avr@mem@get{\the\avr@addr}{\avr@Rd}%
\avr@reg@set{\avr@Rd}{#3}%
\avr@pc@inc%
}
% ST Y+q <- R
\csdef{avr@instr@special@10.0..1.....1...}..#1.#2.#3.#4\@nnil{%
\avr@debug{ST Y+#1#2#4 <- reg(#3)}%
\avr@regw@get{\csuse{avr@Y}}{\@@addr}%
\avr@reg@get{#3}{\avr@Rd}%
\avr@bin@tocount{\@@addr}{\avr@addr}%
\avr@bin@tocount{00#1#2#4}{\avr@count@tmpa}%
\advance \avr@addr by \avr@count@tmpa\relax%
\avr@count@overflow{\avr@addr}\relax%
\avr@mem@set{\avr@Rd}{\the\avr@addr}%
\avr@pc@inc%
}
% ST Z+q <- R
\csdef{avr@instr@special@10.0..1.....0...}..#1.#2.#3.#4\@nnil{%
\avr@debug{ST Z+#1#2#4 <- reg(#3)}%
\avr@regw@get{\csuse{avr@Z}}{\@@addr}%
\avr@reg@get{#3}{\avr@Rd}%
\avr@bin@tocount{\@@addr}{\avr@addr}%
\avr@bin@tocount{00#1#2#4}{\avr@count@tmpa}%
\advance \avr@addr by \avr@count@tmpa\relax%
\avr@count@overflow{\avr@addr}\relax%
\avr@mem@set{\avr@Rd}{\the\avr@addr}%
\avr@pc@inc%
}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% Misc
......
......@@ -119,6 +119,24 @@
\edef#2{\csuse{avr@reg@#1}}%
}
\csdef{avr@X}{1101}
\csdef{avr@Y}{1110}
\csdef{avr@Z}{1111}
\def\avr@regw@get#1#2{%
\avr@reg@get{#11}{\@@high}%
\avr@reg@get{#10}{\@@low}%
\edef#2{\@@high \@@low}%
}
\def\avr@regw@set#1#2{%
\edef\@@value{#1}%
\avr@bin@word@low{\@@value}{\@@low}%
\avr@bin@word@high{\@@value}{\@@high}%
\avr@reg@set{\@@high}{#21}%
\avr@reg@set{\@@low}{#20}%
}
\def\avr@reg@init{%
\avr@reg@set{\avr@zeroes}{00000}%
\avr@reg@set{\avr@zeroes}{00001}%
......@@ -241,11 +259,19 @@
}
\def\avr@mem@set#1#2{% Bitstring, Address (as number)
\ifnum #2 < 96 % 0x60
% FIXME
\avr@error{Not implement access to IO/Regs through memory}%
\fi%
\avr@debug{ MEM W *#2=#1}%
\csxdef{avr@mem@#2}{#1}%
}
\def\avr@mem@get#1#2{% Address (as number), Target Macro
\ifnum #1 < 96 % 0x60
% FIXME
\avr@error{Not implement access to IO/Regs through memory}%
\fi%
\ifcsdef{avr@mem@#1}{%
\edef#2{\csuse{avr@mem@#1}}%
}{%
......
......@@ -21,6 +21,14 @@
}%
}
\def\avr@test@MEM#1#2{% Tests MEM for value
\avr@mem@get{#1}{\@@MEM}%
\expandafter\ifstrequal\expandafter{\@@MEM}{#2}{%Success
}{%
\avr@error{MEM unequal: #2 != \@@MEM}%
}%
}
% Hook Macro for the tests
\def\avr@test{}
......@@ -381,7 +389,9 @@
\preto\avr@test{\avr@test@ROR}
\begin{filecontents*}{empty-main.c}
int main() { }
int main() {
asm volatile ("break");
}
\end{filecontents*}
\def\avr@test@emptymain{%
......@@ -443,6 +453,79 @@ int main() {
\preto\avr@test{\avr@test@fibRec}
\def\avr@test@LDX{%
\avr@test@setup{LDX}%
\avr@mem@set{11110111}{257}%
\avr@mem@set{11110000}{258}%
\avr@mem@set{11110001}{259}%
\avr@instr@LDI{0}{\csuse{avr@r27}}{00000001}%
\avr@instr@LDI{1}{\csuse{avr@r26}}{00000010}%
\avr@instr@LDX{2}{\csuse{avr@r20}}%
\avr@instr@LDXp{3}{\csuse{avr@r21}}%
\avr@instr@LDmX{4}{\csuse{avr@r22}}%
\avr@instr@LDmX{5}{\csuse{avr@r23}}%
\avr@instr@LDmX{6}{\csuse{avr@r24}}%
\avr@instr@LDmX{7}{\csuse{avr@r24}}%
\avr@instr@stepn{8}%
\avr@test@REG{r20}{11110000}
\avr@test@REG{r21}{11110000}
\avr@test@REG{r22}{11110000}
\avr@test@REG{r23}{11110111}
\avr@test@REG{r24}{00000000}
\avr@test@REG{r26}{11111111}
\avr@test@REG{r27}{00000000}
}
\preto\avr@test{\avr@test@LDX}
\def\avr@test@STZ{%
\avr@test@setup{STZ}%
\avr@instr@LDI{0}{\csuse{avr@r31}}{00000001}%
\avr@instr@LDI{1}{\csuse{avr@r30}}{00000010}%
\avr@instr@STZ{2}{\csuse{avr@r30}}%
\avr@instr@STmZ{3}{\csuse{avr@r30}}%
\avr@instr@STZp{4}{\csuse{avr@r0}}%
\avr@instr@STZp{5}{\csuse{avr@r0}}%
\avr@instr@stepn{4}%
\avr@test@MEM{258}{00000010}
\avr@test@MEM{257}{00000010}
\avr@instr@stepn{2}%
\avr@test@MEM{258}{00000000}
\avr@test@MEM{257}{00000000}
}
\preto\avr@test{\avr@test@STZ}
\begin{filecontents*}{complex-memory.c}
#include <avr/io.h>
volatile char foo[30];
int main() {
foo[0] = 23;
foo[1] = 42;
foo[2] = foo[0] + foo[1];
asm volatile ("break");
}
\end{filecontents*}
\def\avr@test@complexMemory{%
\avr@test@setup{Complex Memory Operations}%
\avrloadc{complex-memory.c}
\avr@instr@stepn{1000}
\avr@test@MEM{96}{00010111} % 23
\avr@test@MEM{97}{00101010} % 42
\avr@test@MEM{98}{01000001} % 65
}
\preto\avr@test{\avr@test@complexMemory}
%%% Local Variables:
%%% mode: latex
......
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