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:
parent
6183531abd
commit
44fe73ff8f
@ -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%
|
||||||
|
@ -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
|
||||||
|
@ -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:
|
||||||
**/
|
**/
|
||||||
|
@ -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:
|
||||||
*/
|
*/
|
||||||
|
@ -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
26
tests/shift.c
Normal 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:
|
||||||
|
*/
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user