1
0
mirror of synced 2024-11-22 04:54:24 +01:00

SBC/CPC: Fix Calculation of Zero Flag

For the Sub/Compare with carry, the old Z flag is also used to
AND the newZ:

  newZ = (result==0) & oldZ
This commit is contained in:
Christian Dietrich 2014-09-29 22:59:42 +02:00
parent 6183531abd
commit 44fe73ff8f
7 changed files with 100 additions and 30 deletions

View File

@ -225,9 +225,12 @@
\avr@reg@get{1#5#6#7#8}{\avr@Rd}% \avr@reg@get{1#5#6#7#8}{\avr@Rd}%
\def\avr@Rr{#1#2#3#4#9}% \def\avr@Rr{#1#2#3#4#9}%
\avr@flag@get C \@@carry% \avr@flag@get C \@@carry%
\avr@flag@get Z \@@oldZ%
\xdef \avr@instr@extracarry {\avr@bit@negate \@@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}% \avr@debug{SBCI - \%#2#3#4#5#6 <- #2#3#4#5#6(=\avr@Rd) - \avr@Rr -\@@carry}%
\csuse{avr@instr@subber@helper}% \csuse{avr@instr@subber@helper}%
\avr@flag@get Z \@@newZ%
\avr@flag@set Z {\avr@bit@and \@@oldZ \@@newZ}%
% Set the result register % Set the result register
\avr@reg@set{\avr@Rx}{1#5#6#7#8}% \avr@reg@set{\avr@Rx}{1#5#6#7#8}%
\avr@pc@inc% \avr@pc@inc%
@ -251,9 +254,12 @@
\avr@reg@get{#1#7}{\avr@Rr}% \avr@reg@get{#1#7}{\avr@Rr}%
\avr@reg@get{#2#3#4#5#6}{\avr@Rd}% \avr@reg@get{#2#3#4#5#6}{\avr@Rd}%
\avr@flag@get C \@@carry% \avr@flag@get C \@@carry%
\avr@flag@get Z \@@oldZ%
\xdef \avr@instr@extracarry {\avr@bit@negate \@@carry}% \xdef \avr@instr@extracarry {\avr@bit@negate \@@carry}%
\avr@debug{CPC - #2#3#4#5#6(=\avr@Rd) - \%#1#7(=\avr@Rr)}% \avr@debug{CPC - #2#3#4#5#6(=\avr@Rd) - \%#1#7(=\avr@Rr) - \@@carry}%
\csuse{avr@instr@subber@helper}% \csuse{avr@instr@subber@helper}%
\avr@flag@get Z \@@newZ%
\avr@flag@set Z {\avr@bit@and \@@oldZ \@@newZ}%
% Do not set the output register % Do not set the output register
\avr@pc@inc% \avr@pc@inc%
} }
@ -415,8 +421,9 @@
}% }%
\avr@flag@set C {\@@and {\@@not \@@X} \@@D}% \avr@flag@set C {\@@and {\@@not \@@X} \@@D}%
\avr@flag@set N \@@X% \avr@flag@set N \@@X%
\avr@flag@set V {\@@and {\@@not \@@D} \@@X}% \edef\@@V{\@@and {\@@not \@@D} \@@X}%
\avr@flag@set S {\@@xor \@@X {\@@and {\@@not \@@D} \@@X}}% \avr@flag@set V \@@V%
\avr@flag@set S {\@@xor \@@X \@@V}%
% Set the Result % Set the Result
\avr@regw@set{\avr@Rx}{11#3#4}% \avr@regw@set{\avr@Rx}{11#3#4}%
\avr@pc@inc% \avr@pc@inc%

View File

@ -34,6 +34,7 @@
}{% }{%
\avr@error{UDR unequal: #1 != \avr@UDR}% \avr@error{UDR unequal: #1 != \avr@UDR}%
}% }%
\def\avr@UDR{}%
} }
% Hook Macro for the tests % Hook Macro for the tests

View File

@ -17,31 +17,25 @@ int
main(void) main(void)
{ {
stdout = &mystdout; stdout = &mystdout;
printf("Hello, world!");
volatile float a = 0.23;
volatile float b = 0.43;
printf("%.2f", 1/ (a * b * 3));
asm volatile("break;"); asm volatile("break;");
volatile float foo = 0.23;
printf("%.2f", foo);
asm volatile("break;");
return 0; return 0;
} }
/** /**
check-name: Print to Stdout and Float check-name: Calculate with floats
compiler-opts: -Wl,-u,vfprintf -lm -lprintf_flt
check-start: check-start:
\avr@instr@stepn{100000} \avr@instr@stepn{100000}
\avr@test@UDR{Hello, world!} \avr@test@UDR{3.37}
\xdef\avr@UDR{}
\avr@instr@stepn{100000}
\avr@test@UDR{0.23}
\def\avr@UDR{}
check-end: check-end:
**/ **/

View File

@ -17,8 +17,11 @@ int main() {
volatile uint16_t y = 55; volatile uint16_t y = 55;
foo[5] = x * y; foo[5] = x * y;
foo[20] = 165;
itoa((unsigned char)foo[20], &foo[6], 10);
itoa((signed char)foo[20], &foo[9], 10);
itoa(165, &foo[6], 10);
asm volatile ("break"); asm volatile ("break");
} }
@ -41,5 +44,9 @@ int main() {
\avr@test@MEM{103}{00110110} % '6' \avr@test@MEM{103}{00110110} % '6'
\avr@test@MEM{104}{00110101} % '5' \avr@test@MEM{104}{00110101} % '5'
\avr@test@MEM{105}{00101101} % '-'
\avr@test@MEM{106}{00111001} % '9'
\avr@test@MEM{107}{00110001} % '1'
check-end: check-end:
*/ */

View File

@ -1,20 +1,47 @@
#include <avr/io.h> #include <avr/io.h>
#include <stdio.h> #include <stdio.h>
volatile char buffer[30]; char buffer[30];
volatile char buf[3];
static int uart_putchar(char c, FILE *stream);
static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL,
_FDEV_SETUP_WRITE);
static int
uart_putchar(char c, FILE *stream)
{
UDR = c;
return 0;
}
volatile uint16_t xxx = 165;
int int
main(void) main(void)
{ {
asm volatile("break;"); stdout = &mystdout;
buf[0] = 'x';
buf[1] = 'y';
buf[2] = '\0';
puts(buf);
// sprintf(buffer, "%d", xxx);
__ultoa_invert(xxx, buffer, 10);
asm volatile("break;"); asm volatile("break;");
printf(":%c", buf[0]);
asm volatile("break;");
printf(":%d:", buf[1]);
asm volatile("break;");
volatile float x=0.23;
printf(":%.2f:", x);
asm volatile("break;");
return 0; return 0;
} }
@ -22,15 +49,21 @@ main(void)
/** /**
check-name: Print to Stdout check-name: Print to Stdout
compiler-opts: -Wl,-u,vfprintf -lm -lprintf_flt
check-start: check-start:
\avr@instr@stepn{100000} \avr@instr@stepn{100000}
\avr@instr@executed=0 \avr@test@UDR{xy^10} % ^10 == \n
\avr@instr@stepn{100000} \def\avr@UDR{}
\avr@test@MEM{96}{00110001} % '1' \avr@instr@stepn{100000}
\avr@test@MEM{97}{00110110} % '6' \avr@test@UDR{:x}
\avr@test@MEM{98}{00110101} % '5'
\avr@instr@stepn{100000}
\avr@test@UDR{:121:}
\avr@instr@stepn{100000}
\avr@test@UDR{:0.23:}
check-end: check-end:
**/ **/

26
tests/shift.c Normal file
View File

@ -0,0 +1,26 @@
#include <avr/io.h>
volatile char foo[30];
int main() {
foo[0] = 5;
foo[1] = 42;
foo[2] = foo[1] >> foo[0];
foo[3] = foo[1] << (foo[0]>>2);
asm volatile ("break");
}
/*
check-name: Shift Operations
check-start:
\avr@instr@stepn{1000}
\avr@test@MEM{96}{00000101} % 5
\avr@test@MEM{97}{00101010} % 42
\avr@test@MEM{98}{00000001} % 0
\avr@test@MEM{99}{01010100} % 42
check-end:
*/

View File

@ -96,7 +96,8 @@ do_test()
echo -n "TEST $test_name ($file)" echo -n "TEST $test_name ($file)"
cp HEADER "$file".tex cp HEADER "$file".tex
echo "\avrloadc[-lm -Os -mmcu=atmega8]{$file}" >> "$file".tex get_value compiler-opts "$file"
echo "\avrloadc[-Os -mmcu=atmega8 $last_result]{$file}" >> "$file".tex
awk '/check-start/,/check-end/ {print}' $file \ awk '/check-start/,/check-end/ {print}' $file \
| egrep -v 'check-(start|end)' >> "$file".tex | egrep -v 'check-(start|end)' >> "$file".tex
@ -120,7 +121,8 @@ do_test()
test_failed=1 test_failed=1
else else
get_value BREAK "$file".output get_value BREAK "$file".output
echo " ($last_result)" echo " ($last_result)" | sed 's/ instructions//' | tr -d "\n"
echo
fi fi
if [ "$test_failed" -eq "1" ]; then if [ "$test_failed" -eq "1" ]; then